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"));
+}