diff --git a/CHANGELOG.md b/CHANGELOG.md index d3777eb..47aa553 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,9 @@ All notable changes to this project will be documented in this file. ## [Unreleased] ### Chaned -- Fixed string parsing by correctly handling "string continue" sequences +- Fixed (byte) string literal parsing by: + - Correctly handling "string continue" sequences + - Correctly converting `\n\r` into `\n` ## [0.2.1] - 2021-06-04 diff --git a/src/bytestr/tests.rs b/src/bytestr/tests.rs index 414dd1a..3029b2c 100644 --- a/src/bytestr/tests.rs +++ b/src/bytestr/tests.rs @@ -32,7 +32,7 @@ fn simple() { #[test] fn special_whitespace() { - let strings = ["\n", "\t", "foo\tbar", "baz\n", "\r\n"]; + let strings = ["\n", "\t", "foo\tbar", "baz\n"]; for &s in &strings { let input = format!(r#"b"{}""#, s); @@ -97,6 +97,18 @@ bar", true, None); bar", false, Some(0)); } +#[test] +fn crlf_newlines() { + let lit = ByteStringLit::parse("b\"foo\r\nbar\"").expect("failed to parse"); + assert_eq!(lit.value(), b"foo\nbar"); + + let lit = ByteStringLit::parse("b\"\r\nbar\"").expect("failed to parse"); + assert_eq!(lit.value(), b"\nbar"); + + let lit = ByteStringLit::parse("b\"foo\r\n\"").expect("failed to parse"); + assert_eq!(lit.value(), b"foo\n"); +} + #[test] fn raw_byte_string() { check!(br"", false, Some(0)); diff --git a/src/escape.rs b/src/escape.rs index b4b7e03..c406c09 100644 --- a/src/escape.rs +++ b/src/escape.rs @@ -141,8 +141,16 @@ pub(crate) fn unescape_string( i += len; end_last_escape = i; } - b'\r' if input.as_bytes()[i + 1] != b'\n' - => return Err(perr(i, IsolatedCr)), + b'\r' => { + if input.as_bytes()[i + 1] == b'\n' { + value.push_str(&input[end_last_escape..i]); + value.push('\n'); + i += 2; + end_last_escape = i; + } else { + return Err(perr(i, IsolatedCr)) + } + } b'"' => return Err(perr(i + 1..input.len(), UnexpectedChar)), b if !E::SUPPORTS_UNICODE && !b.is_ascii() => return Err(perr(i, NonAsciiInByteLiteral)), diff --git a/src/string/tests.rs b/src/string/tests.rs index 75c65af..fb16a15 100644 --- a/src/string/tests.rs +++ b/src/string/tests.rs @@ -36,7 +36,7 @@ fn simple() { #[test] fn special_whitespace() { - let strings = ["\n", "\t", "foo\tbar", "🦊\n", "\r\n"]; + let strings = ["\n", "\t", "foo\tbar", "🦊\n"]; for &s in &strings { let input = format!(r#""{}""#, s); @@ -131,6 +131,18 @@ fn string_continue() { bar", false, Some(0)); } +#[test] +fn crlf_newlines() { + let lit = StringLit::parse("\"foo\r\nbar\"").expect("failed to parse"); + assert_eq!(lit.value(), "foo\nbar"); + + let lit = StringLit::parse("\"\r\nbar\"").expect("failed to parse"); + assert_eq!(lit.value(), "\nbar"); + + let lit = StringLit::parse("\"лиса\r\n\"").expect("failed to parse"); + assert_eq!(lit.value(), "лиса\n"); +} + #[test] fn raw_string() { check!(r"", false, Some(0));