Rollup merge of #70681 - rcoh:russell/70677-raw-str-panic, r=petrochenkov
Handle unterminated raw strings with no #s properly 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. Fixes #70677 r? @petrochenkov cc @Centril
This commit is contained in:
commit
ec0da7222d
@ -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`
|
||||
@ -197,7 +201,7 @@ pub fn validate(self) -> Result<ValidatedRawStr, LexRawStrError> {
|
||||
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,
|
||||
@ -687,6 +691,7 @@ fn raw_double_quoted_string(&mut self, prefix_len: usize) -> UnvalidatedRawStr {
|
||||
_ => {
|
||||
return UnvalidatedRawStr {
|
||||
valid_start,
|
||||
valid_end: false,
|
||||
n_start_hashes,
|
||||
n_end_hashes: 0,
|
||||
possible_terminator_offset,
|
||||
@ -702,6 +707,7 @@ fn raw_double_quoted_string(&mut self, prefix_len: usize) -> UnvalidatedRawStr {
|
||||
if self.is_eof() {
|
||||
return UnvalidatedRawStr {
|
||||
valid_start,
|
||||
valid_end: false,
|
||||
n_start_hashes,
|
||||
n_end_hashes: max_hashes,
|
||||
possible_terminator_offset,
|
||||
@ -727,6 +733,7 @@ fn raw_double_quoted_string(&mut self, prefix_len: usize) -> UnvalidatedRawStr {
|
||||
if n_end_hashes == n_start_hashes {
|
||||
return UnvalidatedRawStr {
|
||||
valid_start,
|
||||
valid_end: true,
|
||||
n_start_hashes,
|
||||
n_end_hashes,
|
||||
possible_terminator_offset: None,
|
||||
|
@ -23,6 +23,7 @@ fn test_naked_raw_str() {
|
||||
n_start_hashes: 0,
|
||||
n_end_hashes: 0,
|
||||
valid_start: true,
|
||||
valid_end: true,
|
||||
possible_terminator_offset: None,
|
||||
},
|
||||
Ok(ValidatedRawStr { n_hashes: 0 }),
|
||||
@ -37,6 +38,7 @@ fn test_raw_no_start() {
|
||||
n_start_hashes: 0,
|
||||
n_end_hashes: 0,
|
||||
valid_start: true,
|
||||
valid_end: true,
|
||||
possible_terminator_offset: None,
|
||||
},
|
||||
Ok(ValidatedRawStr { n_hashes: 0 }),
|
||||
@ -51,6 +53,7 @@ fn test_too_many_terminators() {
|
||||
UnvalidatedRawStr {
|
||||
n_start_hashes: 1,
|
||||
n_end_hashes: 1,
|
||||
valid_end: true,
|
||||
valid_start: true,
|
||||
possible_terminator_offset: None,
|
||||
},
|
||||
@ -65,6 +68,7 @@ fn test_unterminated() {
|
||||
UnvalidatedRawStr {
|
||||
n_start_hashes: 1,
|
||||
n_end_hashes: 0,
|
||||
valid_end: false,
|
||||
valid_start: true,
|
||||
possible_terminator_offset: None,
|
||||
},
|
||||
@ -80,6 +84,7 @@ fn test_unterminated() {
|
||||
n_start_hashes: 2,
|
||||
n_end_hashes: 1,
|
||||
valid_start: true,
|
||||
valid_end: false,
|
||||
possible_terminator_offset: Some(7),
|
||||
},
|
||||
Err(LexRawStrError::NoTerminator {
|
||||
@ -95,6 +100,7 @@ fn test_unterminated() {
|
||||
n_start_hashes: 2,
|
||||
n_end_hashes: 0,
|
||||
valid_start: true,
|
||||
valid_end: false,
|
||||
possible_terminator_offset: None,
|
||||
},
|
||||
Err(LexRawStrError::NoTerminator {
|
||||
@ -113,9 +119,30 @@ fn test_invalid_start() {
|
||||
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`.
|
Loading…
Reference in New Issue
Block a user