Skip to content

Commit 72f39fa

Browse files
committed
Require newline after carriage returns that follow backslash newline
1 parent 22bf66f commit 72f39fa

File tree

2 files changed

+27
-18
lines changed

2 files changed

+27
-18
lines changed

src/parse.rs

+26-18
Original file line numberDiff line numberDiff line change
@@ -361,14 +361,17 @@ fn cooked_string(input: Cursor) -> Result<Cursor, LexError> {
361361
}
362362
}
363363
Some((_, ch @ '\n')) | Some((_, ch @ '\r')) => {
364-
if ch == '\r' && chars.next().map_or(true, |(_, ch)| ch != '\n') {
365-
return Err(LexError);
366-
}
367-
while let Some(&(_, ch)) = chars.peek() {
368-
if ch.is_whitespace() {
369-
chars.next();
370-
} else {
371-
break;
364+
let mut last = ch;
365+
loop {
366+
if last == '\r' && chars.next().map_or(true, |(_, ch)| ch != '\n') {
367+
return Err(LexError);
368+
}
369+
match chars.peek() {
370+
Some((_, ch)) if ch.is_whitespace() => {
371+
last = *ch;
372+
chars.next();
373+
}
374+
_ => break,
372375
}
373376
}
374377
}
@@ -392,7 +395,7 @@ fn byte_string(input: Cursor) -> Result<Cursor, LexError> {
392395

393396
fn cooked_byte_string(mut input: Cursor) -> Result<Cursor, LexError> {
394397
let mut bytes = input.bytes().enumerate();
395-
'outer: while let Some((offset, b)) = bytes.next() {
398+
while let Some((offset, b)) = bytes.next() {
396399
match b {
397400
b'"' => {
398401
let input = input.advance(offset + 1);
@@ -414,18 +417,23 @@ fn cooked_byte_string(mut input: Cursor) -> Result<Cursor, LexError> {
414417
Some((_, b'n')) | Some((_, b'r')) | Some((_, b't')) | Some((_, b'\\'))
415418
| Some((_, b'0')) | Some((_, b'\'')) | Some((_, b'"')) => {}
416419
Some((newline, b @ b'\n')) | Some((newline, b @ b'\r')) => {
417-
if b == b'\r' && bytes.next().map_or(true, |(_, b)| b != b'\n') {
418-
return Err(LexError);
419-
}
420+
let mut last = b as char;
420421
let rest = input.advance(newline + 1);
421-
for (offset, ch) in rest.char_indices() {
422-
if !ch.is_whitespace() {
423-
input = rest.advance(offset);
424-
bytes = input.bytes().enumerate();
425-
continue 'outer;
422+
let mut chars = rest.char_indices();
423+
loop {
424+
if last == '\r' && chars.next().map_or(true, |(_, ch)| ch != '\n') {
425+
return Err(LexError);
426+
}
427+
match chars.next() {
428+
Some((_, ch)) if ch.is_whitespace() => last = ch,
429+
Some((offset, _)) => {
430+
input = rest.advance(offset);
431+
bytes = input.bytes().enumerate();
432+
break;
433+
}
434+
None => return Err(LexError),
426435
}
427436
}
428-
break;
429437
}
430438
_ => break,
431439
},

tests/test.rs

+1
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ fn fail() {
205205
fail("\"\\\r \""); // backslash carriage return
206206
fail("'aa'aa");
207207
fail("br##\"\"#");
208+
fail("\"\\\n\u{85}\r\"");
208209
}
209210

210211
#[cfg(span_locations)]

0 commit comments

Comments
 (0)