diff --git a/crates/svg/src/export/output.rs b/crates/svg/src/export/output.rs index 823453a9e..cc7680e90 100644 --- a/crates/svg/src/export/output.rs +++ b/crates/svg/src/export/output.rs @@ -357,7 +357,7 @@ impl Writer<'_> { line(2, ""); line(3, ""); for (term, value) in dublin_core(self.doc) { - line(4, &format!("{}", xml_escape(&value))); + line(4, &format!("{}", xml_text(&value))); } line(3, ""); line(2, ""); diff --git a/crates/svg/tests/it/title_control_chars.rs b/crates/svg/tests/it/title_control_chars.rs index 1dd7fe545..3318ed346 100644 --- a/crates/svg/tests/it/title_control_chars.rs +++ b/crates/svg/tests/it/title_control_chars.rs @@ -53,3 +53,19 @@ fn an_artboard_exported_alone_is_titled_after_it() { d.artboards[1].name = "\u{1}\u{2}".into(); assert_eq!(title(&d, alone(Some(1))).as_deref(), Some("Icons")); } + +#[test] +fn dublin_core_metadata_control_chars_are_filtered() { + let mut d = Document::new(200.0, 200.0); + d.title = "Poster\u{b}v2".into(); + d.metadata.author = "Ann\u{1}e".into(); + d.metadata.description = "a\u{1}b".into(); + d.metadata.keywords = vec!["k\u{1}w".into()]; + d.metadata.copyright_notice = "(c)\u{b}me\u{2}".into(); + let svg = export(&d, &ExportOptions { metadata: true, ..ExportOptions::default() }); + assert!(import(&svg).is_ok(), "export wrote invalid XML: {svg}"); + assert!(svg.contains("Anne")); + assert!(svg.contains("Poster v2")); + assert!(svg.contains("kw")); + assert!(svg.contains("(c) me")); +}