Fix the length displayed for byte string literals with escaped newlines

The length of byte strings containing escaped newlines is displayed two
bytes longer when the first escaped character is a newline.

This is due to a small bug in handling the first escaped newline in
string literals.

Closes #13567
This commit is contained in:
Noritada Kobayashi 2022-11-07 19:25:07 +09:00
parent d03c1c87d4
commit 180b4cedec

View file

@ -209,17 +209,19 @@ impl ast::String {
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
let mut buf = String::new();
let mut text_iter = text.chars();
let mut prev = 0;
let mut has_error = false;
unescape_literal(text, Mode::Str, &mut |char_range, unescaped_char| match (
unescaped_char,
buf.capacity() == 0,
) {
(Ok(c), false) => buf.push(c),
(Ok(c), true) if char_range.len() == 1 && Some(c) == text_iter.next() => (),
(Ok(_), true) if char_range.len() == 1 && char_range.start == prev => {
prev = char_range.end
}
(Ok(c), true) => {
buf.reserve_exact(text.len());
buf.push_str(&text[..char_range.start]);
buf.push_str(&text[..prev]);
buf.push(c);
}
(Err(_), _) => has_error = true,
@ -252,17 +254,19 @@ impl ast::ByteString {
let text = &text[self.text_range_between_quotes()? - self.syntax().text_range().start()];
let mut buf: Vec<u8> = Vec::new();
let mut text_iter = text.chars();
let mut prev = 0;
let mut has_error = false;
unescape_literal(text, Mode::ByteStr, &mut |char_range, unescaped_char| match (
unescaped_char,
buf.capacity() == 0,
) {
(Ok(c), false) => buf.push(c as u8),
(Ok(c), true) if char_range.len() == 1 && Some(c) == text_iter.next() => (),
(Ok(_), true) if char_range.len() == 1 && char_range.start == prev => {
prev = char_range.end
}
(Ok(c), true) => {
buf.reserve_exact(text.len());
buf.extend_from_slice(text[..char_range.start].as_bytes());
buf.extend_from_slice(text[..prev].as_bytes());
buf.push(c as u8);
}
(Err(_), _) => has_error = true,
@ -445,6 +449,12 @@ mod tests {
check_string_value(r"\foobar", None);
check_string_value(r"\nfoobar", "\nfoobar");
check_string_value(r"C:\\Windows\\System32\\", "C:\\Windows\\System32\\");
check_string_value(r"\x61bcde", "a\x62cde");
check_string_value(
r"a\
bcde", "a\
bcde",
);
}
#[test]