Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Avoid possible infinite loop when next_point reaching the end of file #103521

Merged
merged 1 commit into from
Nov 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 3 additions & 5 deletions compiler/rustc_span/src/source_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -855,7 +855,8 @@ impl SourceMap {
/// Returns a new span representing the next character after the end-point of this span.
/// Special cases:
/// - if span is a dummy one, returns the same span
/// - if next_point reached the end of source, return span with lo = hi
/// - if next_point reached the end of source, return a span exceeding the end of source,
/// which means sm.span_to_snippet(next_point) will get `Err`
/// - respect multi-byte characters
pub fn next_point(&self, sp: Span) -> Span {
if sp.is_dummy() {
Expand All @@ -864,9 +865,6 @@ impl SourceMap {
let start_of_next_point = sp.hi().0;

let width = self.find_width_of_character_at_span(sp, true);
if width == 0 {
return Span::new(sp.hi(), sp.hi(), sp.ctxt(), None);
}
// If the width is 1, then the next span should only contain the next char besides current ending.
// However, in the case of a multibyte character, where the width != 1, the next span should
// span multiple bytes to include the whole character.
Expand Down Expand Up @@ -938,7 +936,7 @@ impl SourceMap {
// Ensure indexes are also not malformed.
if start_index > end_index || end_index > source_len - 1 {
debug!("find_width_of_character_at_span: source indexes are malformed");
return 0;
return 1;
}

let src = local_begin.sf.external_src.borrow();
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_span/src/source_map/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -511,16 +511,17 @@ fn test_next_point() {
assert_eq!(span.lo().0, 4);
assert_eq!(span.hi().0, 5);

// A non-empty span at the last byte should advance to create an empty
// span pointing at the end of the file.
// Reaching to the end of file, return a span that will get error with `span_to_snippet`
let span = Span::with_root_ctxt(BytePos(4), BytePos(5));
let span = sm.next_point(span);
assert_eq!(span.lo().0, 5);
assert_eq!(span.hi().0, 5);
assert_eq!(span.hi().0, 6);
assert!(sm.span_to_snippet(span).is_err());

// Empty span pointing just past the last byte.
// Reaching to the end of file, return a span that will get error with `span_to_snippet`
let span = Span::with_root_ctxt(BytePos(5), BytePos(5));
let span = sm.next_point(span);
assert_eq!(span.lo().0, 5);
assert_eq!(span.hi().0, 5);
assert_eq!(span.hi().0, 6);
assert!(sm.span_to_snippet(span).is_err());
}
5 changes: 5 additions & 0 deletions src/test/ui/parser/issue-103451.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// error-pattern: this file contains an unclosed delimiter
// error-pattern: expected value, found struct `R`
struct R { }
struct S {
x: [u8; R
32 changes: 32 additions & 0 deletions src/test/ui/parser/issue-103451.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
error: this file contains an unclosed delimiter
--> $DIR/issue-103451.rs:5:15
|
LL | struct S {
| - unclosed delimiter
LL | x: [u8; R
| - ^
| |
| unclosed delimiter

error: this file contains an unclosed delimiter
--> $DIR/issue-103451.rs:5:15
|
LL | struct S {
| - unclosed delimiter
LL | x: [u8; R
| - ^
| |
| unclosed delimiter

error[E0423]: expected value, found struct `R`
--> $DIR/issue-103451.rs:5:13
|
LL | struct R { }
| ------------ `R` defined here
LL | struct S {
LL | x: [u8; R
| ^ help: use struct literal syntax instead: `R {}`

error: aborting due to 3 previous errors

For more information about this error, try `rustc --explain E0423`.