From 1dd585ca54564005a311bdca46cd1894c68459ac Mon Sep 17 00:00:00 2001 From: Chris Hennick <4961925+Pr0methean@users.noreply.github.com> Date: Fri, 3 May 2024 12:28:04 -0700 Subject: [PATCH 1/2] Switch to using std::ascii::escape_default This will escape all non-ASCII bytes, rather than just the allowlisted special characters. --- escape_string/src/lib.rs | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/escape_string/src/lib.rs b/escape_string/src/lib.rs index 62c6ba6..4f9845b 100644 --- a/escape_string/src/lib.rs +++ b/escape_string/src/lib.rs @@ -150,24 +150,12 @@ pub fn escape<'a>(text: &'a str) -> Cow<'a, str> { let mut owned = None; for pos in 0..bytes.len() { - let special = match bytes[pos] { - 0x07 => Some(b'a'), - 0x08 => Some(b'b'), - b'\t' => Some(b't'), - b'\n' => Some(b'n'), - 0x0b => Some(b'v'), - 0x0c => Some(b'f'), - b'\r' => Some(b'r'), - b' ' => Some(b' '), - b'\\' => Some(b'\\'), - _ => None, - }; - if let Some(s) = special { + let special: Box<[u8]> = std::ascii::escape_default(bytes[pos]).collect(); + if special.len() > 1 { if owned.is_none() { owned = Some(bytes[0..pos].to_owned()); } - owned.as_mut().unwrap().push(b'\\'); - owned.as_mut().unwrap().push(s); + owned.as_mut().unwrap().push(special); } else if let Some(owned) = owned.as_mut() { owned.push(bytes[pos]); } From 41637aac2a783508686a5f33ef26205a5af01588 Mon Sep 17 00:00:00 2001 From: Chris Hennick <4961925+Pr0methean@users.noreply.github.com> Date: Wed, 5 Jun 2024 18:17:16 -0700 Subject: [PATCH 2/2] Optimization: check for non-ASCII character before allocating space for escape sequence --- escape_string/src/lib.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/escape_string/src/lib.rs b/escape_string/src/lib.rs index 4f9845b..e4b232f 100644 --- a/escape_string/src/lib.rs +++ b/escape_string/src/lib.rs @@ -150,12 +150,11 @@ pub fn escape<'a>(text: &'a str) -> Cow<'a, str> { let mut owned = None; for pos in 0..bytes.len() { - let special: Box<[u8]> = std::ascii::escape_default(bytes[pos]).collect(); - if special.len() > 1 { + if !(bytes[pos] as char).is_ascii() { if owned.is_none() { owned = Some(bytes[0..pos].to_owned()); } - owned.as_mut().unwrap().push(special); + owned.as_mut().unwrap().expand(std::ascii::escape_default(bytes[pos])); } else if let Some(owned) = owned.as_mut() { owned.push(bytes[pos]); }