Drop U+FFFE and U+FFFF from XFDF/XML form-data export (#3330)

Found while testing crates/xfdf/src/lib.rs:192-209 (esc), used by export_xfdf (:445) and export_data XML (:594-612)

Co-authored-by: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-18 17:06:07 -04:00
committed by GitHub
co-authored by Claude Haiku 5.5
parent 0c9c621a1f
commit 666648349b
2 changed files with 18 additions and 0 deletions
+2
View File
@@ -202,6 +202,8 @@ fn esc(s: &str) -> String {
'\n' => o.push_str("&#10;"),
'\r' => o.push_str("&#13;"),
c if (c as u32) < 0x20 && c != '\n' && c != '\t' => {}
// XML 1.0 noncharacters are not allowed even as raw text.
'\u{FFFE}' | '\u{FFFF}' => {}
c => o.push(c),
}
}
+16
View File
@@ -168,6 +168,22 @@ fn a_replace_text_pair_survives_an_xfdf_round_trip() {
assert_eq!(comment_view(&dst), comment_view(&src), "the pair and its thread survive");
}
#[test]
fn xml_exports_drop_xml_noncharacters() {
let mut src = filled();
set_value(&mut src, "Name", &FieldValue::Text("a\u{FFFE}b\u{FFFF}c".into())).unwrap();
let xfdf = export_xfdf(&src, false, true, "f.pdf");
let doc = roxmltree::Document::parse(&xfdf).unwrap_or_else(|e| panic!("XFDF is not well-formed: {e}: {xfdf:?}"));
let value = doc
.descendants()
.find(|n| n.has_tag_name("field") && n.attribute("name") == Some("Name"))
.and_then(|n| n.children().find(|c| c.has_tag_name("value")))
.and_then(|n| n.text());
assert_eq!(value, Some("abc"));
let data = export_data(&src, Format::Xml);
roxmltree::Document::parse(&data).unwrap_or_else(|e| panic!("XML is not well-formed: {e}: {data:?}"));
}
#[test]
fn xml_exports_preserve_whitespace_in_field_names() {
let names = ["Line\nName", "Line\tName", "Line\rName", "Line\r\nName", "\t Leading\nTrailing \t", "Line Name"];