Filter control characters in SVG export title and description

Found while testing crates/svg/src/export.rs:138 and :143

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-20 03:15:47 +07:00
committed by bflatastic
co-authored by Claude Haiku 5.5
parent 5397ad22e7
commit 05017111ba
2 changed files with 28 additions and 2 deletions
+2 -2
View File
@@ -135,12 +135,12 @@ fn write(doc: &Document, opts: &ExportOptions, native: Option<&[u8]>, id_prefix:
}
if !doc.title.is_empty() {
out.push_str(&w.indent(1));
out.push_str(&format!("<title>{}</title>{nl}", xml_escape(&doc.title)));
out.push_str(&format!("<title>{}</title>{nl}", xml_text(&doc.title)));
}
// File Info's description.
if !doc.metadata.description.trim().is_empty() {
out.push_str(&w.indent(1));
out.push_str(&format!("<desc>{}</desc>{nl}", xml_escape(&doc.metadata.description)));
out.push_str(&format!("<desc>{}</desc>{nl}", xml_text(&doc.metadata.description)));
}
// Window › SVG Interactivity › Link JavaScript Files.
for file in &doc.svg_scripts {
+26
View File
@@ -0,0 +1,26 @@
// Integration tests: unwrapping and panicking on failure is fine here, unlike in shipped code (AGENTS.md › Robustness).
#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
use vectorcraft_doc::Document;
use vectorcraft_svg::{ExportOptions, export, import};
#[test]
fn title_and_description_control_chars_are_filtered() {
let mut d = Document::new(200.0, 200.0);
d.title = "Poster\u{b}v2".into();
d.metadata.description = "a\u{1}b".into();
let svg = export(&d, &ExportOptions::default());
assert!(import(&svg).is_ok(), "export wrote invalid XML: {svg}");
assert!(svg.contains("<title>Poster v2</title>"));
assert!(svg.contains("<desc>ab</desc>"));
}
#[test]
fn title_and_description_markup_is_escaped() {
let mut d = Document::new(200.0, 200.0);
d.title = "A & <B>".into();
d.metadata.description = "x & y".into();
let svg = export(&d, &ExportOptions::default());
assert!(import(&svg).is_ok(), "export wrote invalid XML: {svg}");
assert!(svg.contains("<title>A &amp; &lt;B&gt;</title>"));
assert!(svg.contains("<desc>x &amp; y</desc>"));
}