diff --git a/src/syntax/lexer.rs b/src/syntax/lexer.rs index 4d25672..0370041 100644 --- a/src/syntax/lexer.rs +++ b/src/syntax/lexer.rs @@ -103,6 +103,12 @@ impl<'a> Lexer<'a> { } b'\\' => { self.pos += 1; + if self.bytes.get(self.pos) == Some(&b'\n') { + // An escaped newline is not a JSON continuation, + // so the newline still terminates the line. + self.error(start, "unterminated string"); + break; + } if self.pos < self.bytes.len() { self.advance_char(); } @@ -259,6 +265,15 @@ mod tests { assert_eq!(errors.len(), 1); } + #[test] + fn backslash_before_newline_ends_the_string() { + let (tokens, errors) = tokenize("\"C:\\\ntrue"); + assert_eq!(tokens[0].kind, SyntaxKind::Str); + assert_eq!(tokens[0].text, "\"C:\\"); + assert_eq!(errors.len(), 1); + assert_eq!(tokens.last().unwrap().kind, SyntaxKind::True); + } + #[test] fn invalid_number_reports_error() { let (_, errors) = tokenize("1.2.3");