From 38e81bff04a76215e216f1a0bc7e482d6d8f311f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 2 Apr 2023 22:54:50 -0700 Subject: [PATCH] Circumvent clippy::octal_escapes lint in generated literals --- src/fallback.rs | 29 +++++++++++++++++++++-------- tests/test.rs | 4 ++-- 2 files changed, 23 insertions(+), 10 deletions(-) diff --git a/src/fallback.rs b/src/fallback.rs index 214843ae..5aa42642 100644 --- a/src/fallback.rs +++ b/src/fallback.rs @@ -958,12 +958,20 @@ impl Literal { pub fn string(t: &str) -> Literal { let mut repr = String::with_capacity(t.len() + 2); repr.push('"'); - for c in t.chars() { - if c == '\'' { + let mut chars = t.chars(); + while let Some(ch) = chars.next() { + if ch == '\0' + && chars + .as_str() + .starts_with(|next| '0' <= next && next <= '7') + { + // circumvent clippy::octal_escapes lint + repr.push_str("\\x00"); + } else if ch == '\'' { // escape_debug turns this into "\'" which is unnecessary. - repr.push(c); + repr.push(ch); } else { - repr.extend(c.escape_debug()); + repr.extend(ch.escape_debug()); } } repr.push('"'); @@ -985,16 +993,21 @@ impl Literal { pub fn byte_string(bytes: &[u8]) -> Literal { let mut escaped = "b\"".to_string(); - for b in bytes { + let mut bytes = bytes.iter(); + while let Some(&b) = bytes.next() { #[allow(clippy::match_overlapping_arm)] - match *b { - b'\0' => escaped.push_str(r"\0"), + match b { + b'\0' => escaped.push_str(match bytes.as_slice().get(0) { + // circumvent clippy::octal_escapes lint + Some(b'0'..=b'7') => r"\x00", + _ => r"\0", + }), b'\t' => escaped.push_str(r"\t"), b'\n' => escaped.push_str(r"\n"), b'\r' => escaped.push_str(r"\r"), b'"' => escaped.push_str("\\\""), b'\\' => escaped.push_str("\\\\"), - b'\x20'..=b'\x7E' => escaped.push(*b as char), + b'\x20'..=b'\x7E' => escaped.push(b as char), _ => { let _ = write!(escaped, "\\x{:02X}", b); } diff --git a/tests/test.rs b/tests/test.rs index 4c2de3c8..31881045 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -116,7 +116,7 @@ fn literal_string() { assert_eq!(Literal::string("didn't").to_string(), "\"didn't\""); assert_eq!( Literal::string("a\00b\07c\08d\0e\0").to_string(), - "\"a\\00b\\07c\\08d\\0e\\0\"", + "\"a\\x000b\\x007c\\08d\\0e\\0\"", ); } @@ -153,7 +153,7 @@ fn literal_byte_string() { ); assert_eq!( Literal::byte_string(b"a\00b\07c\08d\0e\0").to_string(), - "b\"a\\00b\\07c\\08d\\0e\\0\"", + "b\"a\\x000b\\x007c\\08d\\0e\\0\"", ); }