use alloc::string::String;
use core::fmt;
use crate::unicode::*;
#[derive(Clone, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Default)]
pub struct UntrustedString(pub String);
impl fmt::Display for UntrustedString {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
PrintableString(&self.0).fmt(f)
}
}
#[derive(Debug, PartialEq)]
pub struct PrintableString<'a>(pub &'a str);
impl<'a> fmt::Display for PrintableString<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
use core::fmt::Write;
for c in self.0.chars() {
let is_other = is_unicode_general_category_other(c);
let is_unassigned = is_unicode_general_category_unassigned(c);
let c = if c.is_control() || is_other || is_unassigned {
core::char::REPLACEMENT_CHARACTER
} else {
c
};
f.write_char(c)?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::PrintableString;
#[test]
fn displays_printable_string() {
assert_eq!(
format!("{}", PrintableString("I \u{1F496} LDK!\t\u{26A1}")),
"I \u{1F496} LDK!\u{FFFD}\u{26A1}",
);
}
#[test]
fn sanitizes_unicode_bidi_override_characters() {
let rendered = format!("{}", PrintableString("safe\u{202E}cipsxe.exe"));
assert!(
!rendered.contains('\u{202E}'),
"PrintableString left a U+202E RLO override in its output: {:?}",
rendered
);
assert_eq!(format!("{}", PrintableString("x\u{1343F}y\u{13440}z")), "x\u{FFFD}y\u{13440}z");
}
}