#[inline]
pub(crate) fn sanitize_untrusted_display_text(text: &str) -> String {
let mut out = String::with_capacity(text.len());
for ch in text.chars() {
let cp = ch as u32;
let needs_replace = ch == ';'
|| cp < 0x20
|| cp == 0x7F
|| (0x80..=0x9F).contains(&cp)
|| cp == 0x2028
|| cp == 0x2029
|| cp == 0x200E
|| cp == 0x200F
|| (0x202A..=0x202E).contains(&cp)
|| (0x2066..=0x2069).contains(&cp);
if needs_replace {
out.push('_');
} else {
out.push(ch);
}
}
out
}
#[cfg(test)]
mod tests {
use super::sanitize_untrusted_display_text;
#[test]
fn preserves_plain_text() {
assert_eq!(
sanitize_untrusted_display_text("safe/path-_.txt"),
"safe/path-_.txt"
);
}
#[test]
fn scrubs_each_injection_character_class() {
let dangerous = [
'\n', '\r', '\x1b', '\x7f', '\u{0085}', '\u{009b}', '\u{2028}', '\u{2029}', '\u{200e}', '\u{200f}', '\u{202e}', '\u{2066}', ';', ];
let input: String = dangerous.iter().collect();
let expected = "_".repeat(dangerous.len());
assert_eq!(sanitize_untrusted_display_text(&input), expected);
}
}