Skip to content

Commit 3ec2d68

Browse files
authored
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
2 parents 076c63f + f543689 commit 3ec2d68

File tree

4 files changed

+49
-1
lines changed

4 files changed

+49
-1
lines changed

src/librustc_lexer/src/lib.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,10 @@ pub enum LiteralKind {
148148
pub struct UnvalidatedRawStr {
149149
/// The prefix (`r###"`) is valid
150150
valid_start: bool,
151+
152+
/// The postfix (`"###`) is valid
153+
valid_end: bool,
154+
151155
/// The number of leading `#`
152156
n_start_hashes: usize,
153157
/// The number of trailing `#`. `n_end_hashes` <= `n_start_hashes`
@@ -197,7 +201,7 @@ impl UnvalidatedRawStr {
197201
let n_start_safe: u16 =
198202
self.n_start_hashes.try_into().map_err(|_| LexRawStrError::TooManyDelimiters)?;
199203

200-
if self.n_start_hashes > self.n_end_hashes {
204+
if self.n_start_hashes > self.n_end_hashes || !self.valid_end {
201205
Err(LexRawStrError::NoTerminator {
202206
expected: self.n_start_hashes,
203207
found: self.n_end_hashes,
@@ -687,6 +691,7 @@ impl Cursor<'_> {
687691
_ => {
688692
return UnvalidatedRawStr {
689693
valid_start,
694+
valid_end: false,
690695
n_start_hashes,
691696
n_end_hashes: 0,
692697
possible_terminator_offset,
@@ -702,6 +707,7 @@ impl Cursor<'_> {
702707
if self.is_eof() {
703708
return UnvalidatedRawStr {
704709
valid_start,
710+
valid_end: false,
705711
n_start_hashes,
706712
n_end_hashes: max_hashes,
707713
possible_terminator_offset,
@@ -727,6 +733,7 @@ impl Cursor<'_> {
727733
if n_end_hashes == n_start_hashes {
728734
return UnvalidatedRawStr {
729735
valid_start,
736+
valid_end: true,
730737
n_start_hashes,
731738
n_end_hashes,
732739
possible_terminator_offset: None,

src/librustc_lexer/src/tests.rs

+27
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ mod tests {
2323
n_start_hashes: 0,
2424
n_end_hashes: 0,
2525
valid_start: true,
26+
valid_end: true,
2627
possible_terminator_offset: None,
2728
},
2829
Ok(ValidatedRawStr { n_hashes: 0 }),
@@ -37,6 +38,7 @@ mod tests {
3738
n_start_hashes: 0,
3839
n_end_hashes: 0,
3940
valid_start: true,
41+
valid_end: true,
4042
possible_terminator_offset: None,
4143
},
4244
Ok(ValidatedRawStr { n_hashes: 0 }),
@@ -51,6 +53,7 @@ mod tests {
5153
UnvalidatedRawStr {
5254
n_start_hashes: 1,
5355
n_end_hashes: 1,
56+
valid_end: true,
5457
valid_start: true,
5558
possible_terminator_offset: None,
5659
},
@@ -65,6 +68,7 @@ mod tests {
6568
UnvalidatedRawStr {
6669
n_start_hashes: 1,
6770
n_end_hashes: 0,
71+
valid_end: false,
6872
valid_start: true,
6973
possible_terminator_offset: None,
7074
},
@@ -80,6 +84,7 @@ mod tests {
8084
n_start_hashes: 2,
8185
n_end_hashes: 1,
8286
valid_start: true,
87+
valid_end: false,
8388
possible_terminator_offset: Some(7),
8489
},
8590
Err(LexRawStrError::NoTerminator {
@@ -95,6 +100,7 @@ mod tests {
95100
n_start_hashes: 2,
96101
n_end_hashes: 0,
97102
valid_start: true,
103+
valid_end: false,
98104
possible_terminator_offset: None,
99105
},
100106
Err(LexRawStrError::NoTerminator {
@@ -113,9 +119,30 @@ mod tests {
113119
n_start_hashes: 1,
114120
n_end_hashes: 0,
115121
valid_start: false,
122+
valid_end: false,
116123
possible_terminator_offset: None,
117124
},
118125
Err(LexRawStrError::InvalidStarter),
119126
);
120127
}
128+
129+
#[test]
130+
fn test_unterminated_no_pound() {
131+
// https://github.com/rust-lang/rust/issues/70677
132+
check_raw_str(
133+
r#"""#,
134+
UnvalidatedRawStr {
135+
n_start_hashes: 0,
136+
n_end_hashes: 0,
137+
valid_start: true,
138+
valid_end: false,
139+
possible_terminator_offset: None,
140+
},
141+
Err(LexRawStrError::NoTerminator {
142+
expected: 0,
143+
found: 0,
144+
possible_terminator_offset: None,
145+
}),
146+
);
147+
}
121148
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// This won't actually panic because of the error comment -- the `"` needs to be
2+
// the last byte in the file (including not having a trailing newline)
3+
// Prior to the fix you get the error: 'expected item, found `r" ...`'
4+
// because the string being unterminated wasn't properly detected.
5+
r" //~ unterminated raw string
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
error[E0748]: unterminated raw string
2+
--> $DIR/issue-70677-panic-on-unterminated-raw-str-at-eof.rs:5:1
3+
|
4+
LL | r"
5+
| ^ unterminated raw string
6+
7+
error: aborting due to previous error
8+
9+
For more information about this error, try `rustc --explain E0748`.

0 commit comments

Comments
 (0)