diff options
| author | Ryan Cumming <etaoins@gmail.com> | 2018-02-25 11:41:08 +1100 |
|---|---|---|
| committer | Ryan Cumming <etaoins@gmail.com> | 2018-02-25 11:41:08 +1100 |
| commit | d27fac618d0e9e054fbc65130788eaacda259a9f (patch) | |
| tree | c00b5ba3bbd4ab1f75df79a0a03f7f84e6b9c4de /src/libsyntax/codemap.rs | |
| parent | 6070d3e47e5e9f15575a3bd33583358b52bc6eda (diff) | |
| download | rust-d27fac618d0e9e054fbc65130788eaacda259a9f.tar.gz rust-d27fac618d0e9e054fbc65130788eaacda259a9f.zip | |
Fix find_width_of_character_at_span bounds check
Commit 0bd96671f0 added bounds checking of our current target byte position to prevent infinite loops. Unfortunately it was comparing the file-relative `target` versus the global relative `file_start_pos` and `file_end_pos`. The result is failing to detect multibyte characters unless their file-relative offset fit within their global offset. This causes other parts of the compiler to generate spans pointing to the middle of a multibyte character which will ultimately panic in `bytepos_to_file_charpos`. Fix by comparing the `target` to the total file size when moving forward and doing checked subtraction when moving backwards. This should preserve the intent of the bounds check while removing the offset confusion. Fixes #48508
Diffstat (limited to 'src/libsyntax/codemap.rs')
| -rw-r--r-- | src/libsyntax/codemap.rs | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index df5845f6c21..5d36f39b2e4 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -705,17 +705,20 @@ impl CodeMap { }; debug!("find_width_of_character_at_span: snippet=`{:?}`", snippet); - let file_start_pos = local_begin.fm.start_pos.to_usize(); - let file_end_pos = local_begin.fm.end_pos.to_usize(); - debug!("find_width_of_character_at_span: file_start_pos=`{:?}` file_end_pos=`{:?}`", - file_start_pos, file_end_pos); - let mut target = if forwards { end_index + 1 } else { end_index - 1 }; debug!("find_width_of_character_at_span: initial target=`{:?}`", target); - while !snippet.is_char_boundary(target - start_index) - && target >= file_start_pos && target <= file_end_pos { - target = if forwards { target + 1 } else { target - 1 }; + while !snippet.is_char_boundary(target - start_index) && target < source_len { + target = if forwards { + target + 1 + } else { + match target.checked_sub(1) { + Some(target) => target, + None => { + break; + } + } + }; debug!("find_width_of_character_at_span: target=`{:?}`", target); } debug!("find_width_of_character_at_span: final target=`{:?}`", target); |
