Skip to content

Commit

Permalink
Merge pull request #380 from dtolnay/octalescape
Browse files Browse the repository at this point in the history
Circumvent clippy::octal_escapes lint in generated literals
  • Loading branch information
dtolnay authored Apr 3, 2023
2 parents c4a3e19 + 6c21627 commit 9c092a3
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 9 deletions.
29 changes: 21 additions & 8 deletions src/fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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('"');
Expand All @@ -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().first() {
// 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);
}
Expand Down
12 changes: 11 additions & 1 deletion tests/test.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
#![allow(
clippy::assertions_on_result_states,
clippy::items_after_statements,
clippy::non_ascii_literal
clippy::non_ascii_literal,
clippy::octal_escapes
)]

use proc_macro2::{Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
Expand Down Expand Up @@ -114,6 +115,11 @@ fn literal_string() {
assert_eq!(Literal::string("foo").to_string(), "\"foo\"");
assert_eq!(Literal::string("\"").to_string(), "\"\\\"\"");
assert_eq!(Literal::string("didn't").to_string(), "\"didn't\"");

let repr = Literal::string("a\00b\07c\08d\0e\0").to_string();
if repr != "\"a\\x000b\\x007c\\u{0}8d\\u{0}e\\u{0}\"" {
assert_eq!(repr, "\"a\\x000b\\x007c\\08d\\0e\\0\"");
}
}

#[test]
Expand Down Expand Up @@ -147,6 +153,10 @@ fn literal_byte_string() {
Literal::byte_string(b"\0\t\n\r\"\\2\x10").to_string(),
"b\"\\0\\t\\n\\r\\\"\\\\2\\x10\"",
);
assert_eq!(
Literal::byte_string(b"a\00b\07c\08d\0e\0").to_string(),
"b\"a\\x000b\\x007c\\08d\\0e\\0\"",
);
}

#[test]
Expand Down

0 comments on commit 9c092a3

Please sign in to comment.