pub(crate) fn escaped_from_raw(src: &[u8], dstlen: usize) -> String {
escape(src, "\\0", dstlen.saturating_sub(1))
}
pub(crate) fn print_escaped(src: &[u8]) -> String {
if src.first().is_none_or(|&c| c == 0) {
return String::new();
}
escape(src, "\\x00", usize::MAX)
}
fn escape(src: &[u8], nul: &str, max: usize) -> String {
let mut out = String::with_capacity(src.len().min(max));
let mut hex = String::new();
for &c in src {
let esc = match c {
0x07 => "\\a",
0x08 => "\\b",
0x0c => "\\f",
b'\n' => "\\n",
b'\r' => "\\r",
b'\t' => "\\t",
0x0b => "\\v",
b'\\' => "\\\\",
b'\'' => "\\'",
b'"' => "\\\"",
0 => nul,
0x20..=0x7e => {
hex.clear();
hex.push(c as char);
&hex
}
_ => {
use std::fmt::Write;
hex.clear();
let _ = write!(hex, "\\x{c:02x}");
&hex
}
};
for ch in esc.chars() {
if out.len() >= max {
return out;
}
out.push(ch);
}
}
out
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_table_is_c_s_and_the_two_forms_differ_only_on_nul() {
let named = b"\x07\x08\x0c\n\r\t\x0b\\'\"";
assert_eq!(escaped_from_raw(named, 80), r#"\a\b\f\n\r\t\v\\\'\""#);
assert_eq!(print_escaped(named), r#"\a\b\f\n\r\t\v\\\'\""#);
assert_eq!(escaped_from_raw(b" ~OK", 80), " ~OK");
assert_eq!(
escaped_from_raw(b"\x03\x1b\x7f\xff", 80),
r"\x03\x1b\x7f\xff"
);
assert_eq!(print_escaped(b"\x03\x1b\x7f\xff"), r"\x03\x1b\x7f\xff");
assert_eq!(escaped_from_raw(b"a\0b", 80), r"a\0b");
assert_eq!(print_escaped(b"a\0b"), r"a\x00b");
}
#[test]
fn the_destination_bound_truncates_the_escaped_stream_mid_pair() {
let crlf: Vec<u8> = b"\r\n".repeat(100);
let tinp = escaped_from_raw(&crlf, 40);
assert_eq!(tinp.len(), 39);
assert!(tinp.ends_with(r"\r\n\r\"), "dangling backslash: {tinp}");
let eos = escaped_from_raw(&crlf, 10);
assert_eq!(eos, r"\r\n\r\n\");
assert_eq!(escaped_from_raw(b"a\tb", 4), r"a\t");
assert_eq!(escaped_from_raw(b"a\tb", 3), r"a\");
assert_eq!(escaped_from_raw(b"\r\n", 5), r"\r\n");
assert_eq!(escaped_from_raw(b"", 40), "");
assert_eq!(escaped_from_raw(b"\xff", 3), r"\x");
}
#[test]
fn print_escaped_prints_nothing_when_the_first_byte_is_nul() {
assert_eq!(print_escaped(b"\0a"), "");
assert_eq!(print_escaped(b"\0"), "");
assert_eq!(print_escaped(b""), "");
assert_eq!(print_escaped(b"a\0b"), r"a\x00b");
assert_eq!(escaped_from_raw(b"\0a", 40), r"\0a");
}
}