Skip to content

Commit

Permalink
Handle unterminated raw strings with no #s properly
Browse files Browse the repository at this point in the history
The modified code to handle parsing raw strings didn't properly account for the case where there was no "#" on either end and erroneously reported this strings as complete. This lead to a panic trying to read off the end of the file.
  • Loading branch information
rcoh committed Apr 2, 2020
1 parent 76b1198 commit f543689
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/librustc_lexer/src/lib.rs
Expand Up @@ -148,6 +148,10 @@ pub enum LiteralKind {
pub struct UnvalidatedRawStr {
/// The prefix (`r###"`) is valid
valid_start: bool,

/// The postfix (`"###`) is valid
valid_end: bool,

/// The number of leading `#`
n_start_hashes: usize,
/// The number of trailing `#`. `n_end_hashes` <= `n_start_hashes`
Expand Down Expand Up @@ -197,7 +201,7 @@ impl UnvalidatedRawStr {
let n_start_safe: u16 =
self.n_start_hashes.try_into().map_err(|_| LexRawStrError::TooManyDelimiters)?;

if self.n_start_hashes > self.n_end_hashes {
if self.n_start_hashes > self.n_end_hashes || !self.valid_end {
Err(LexRawStrError::NoTerminator {
expected: self.n_start_hashes,
found: self.n_end_hashes,
Expand Down Expand Up @@ -687,6 +691,7 @@ impl Cursor<'_> {
_ => {
return UnvalidatedRawStr {
valid_start,
valid_end: false,
n_start_hashes,
n_end_hashes: 0,
possible_terminator_offset,
Expand All @@ -702,6 +707,7 @@ impl Cursor<'_> {
if self.is_eof() {
return UnvalidatedRawStr {
valid_start,
valid_end: false,
n_start_hashes,
n_end_hashes: max_hashes,
possible_terminator_offset,
Expand All @@ -727,6 +733,7 @@ impl Cursor<'_> {
if n_end_hashes == n_start_hashes {
return UnvalidatedRawStr {
valid_start,
valid_end: true,
n_start_hashes,
n_end_hashes,
possible_terminator_offset: None,
Expand Down
27 changes: 27 additions & 0 deletions src/librustc_lexer/src/tests.rs
Expand Up @@ -23,6 +23,7 @@ mod tests {
n_start_hashes: 0,
n_end_hashes: 0,
valid_start: true,
valid_end: true,
possible_terminator_offset: None,
},
Ok(ValidatedRawStr { n_hashes: 0 }),
Expand All @@ -37,6 +38,7 @@ mod tests {
n_start_hashes: 0,
n_end_hashes: 0,
valid_start: true,
valid_end: true,
possible_terminator_offset: None,
},
Ok(ValidatedRawStr { n_hashes: 0 }),
Expand All @@ -51,6 +53,7 @@ mod tests {
UnvalidatedRawStr {
n_start_hashes: 1,
n_end_hashes: 1,
valid_end: true,
valid_start: true,
possible_terminator_offset: None,
},
Expand All @@ -65,6 +68,7 @@ mod tests {
UnvalidatedRawStr {
n_start_hashes: 1,
n_end_hashes: 0,
valid_end: false,
valid_start: true,
possible_terminator_offset: None,
},
Expand All @@ -80,6 +84,7 @@ mod tests {
n_start_hashes: 2,
n_end_hashes: 1,
valid_start: true,
valid_end: false,
possible_terminator_offset: Some(7),
},
Err(LexRawStrError::NoTerminator {
Expand All @@ -95,6 +100,7 @@ mod tests {
n_start_hashes: 2,
n_end_hashes: 0,
valid_start: true,
valid_end: false,
possible_terminator_offset: None,
},
Err(LexRawStrError::NoTerminator {
Expand All @@ -113,9 +119,30 @@ mod tests {
n_start_hashes: 1,
n_end_hashes: 0,
valid_start: false,
valid_end: false,
possible_terminator_offset: None,
},
Err(LexRawStrError::InvalidStarter),
);
}

#[test]
fn test_unterminated_no_pound() {
// https://github.com/rust-lang/rust/issues/70677
check_raw_str(
r#"""#,
UnvalidatedRawStr {
n_start_hashes: 0,
n_end_hashes: 0,
valid_start: true,
valid_end: false,
possible_terminator_offset: None,
},
Err(LexRawStrError::NoTerminator {
expected: 0,
found: 0,
possible_terminator_offset: None,
}),
);
}
}
@@ -0,0 +1,5 @@
// This won't actually panic because of the error comment -- the `"` needs to be
// the last byte in the file (including not having a trailing newline)
// Prior to the fix you get the error: 'expected item, found `r" ...`'
// because the string being unterminated wasn't properly detected.
r" //~ unterminated raw string
@@ -0,0 +1,9 @@
error[E0748]: unterminated raw string
--> $DIR/issue-70677-panic-on-unterminated-raw-str-at-eof.rs:5:1
|
LL | r"
| ^ unterminated raw string

error: aborting due to previous error

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

0 comments on commit f543689

Please sign in to comment.