From 4f9b620dc613b2d9ad347862d587ffc6de8ac16f Mon Sep 17 00:00:00 2001
From: Taha-Mahmoodi <85902429+Taha-Mahmoodi@users.noreply.github.com>
Date: Thu, 22 Oct 2026 16:24:07 +0430
Subject: [PATCH] Fix #3544: an artboard name XML can't hold falls back to the
document title
Review follow-up (CodeRabbit): the blank-name check ran on the raw name, so
a name made only of characters XML can't hold (control characters) wrote an
empty
. The name is sanitised first, then the fallback applies. The
title test covers such a name; it fails without the change.
---
crates/svg/src/export.rs | 7 ++++---
crates/svg/tests/title_control_chars.rs | 3 +++
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/crates/svg/src/export.rs b/crates/svg/src/export.rs
index 45e9438d0..08f0794af 100644
--- a/crates/svg/src/export.rs
+++ b/crates/svg/src/export.rs
@@ -134,11 +134,12 @@ fn write(doc: &Document, opts: &ExportOptions, native: Option<&[u8]>, id_prefix:
out.push_str(&format!("{nl}"));
}
// An artboard exported on its own is named after it (#3544), else after the document.
- let board = opts.artboard.filter(|_| opts.artboard_title).and_then(|i| doc.artboards.get(i)).map(|a| a.name.as_str());
- let title = board.filter(|n| !n.trim().is_empty()).unwrap_or(&doc.title);
+ // A name that is blank once the characters XML can't hold are dropped falls back too.
+ let board = opts.artboard.filter(|_| opts.artboard_title).and_then(|i| doc.artboards.get(i)).map(|a| xml_text(&a.name));
+ let title = board.filter(|n| !n.trim().is_empty()).unwrap_or_else(|| xml_text(&doc.title));
if !title.is_empty() {
out.push_str(&w.indent(1));
- out.push_str(&format!("{}{nl}", xml_text(title)));
+ out.push_str(&format!("{title}{nl}"));
}
// File Info's description.
if !doc.metadata.description.trim().is_empty() {
diff --git a/crates/svg/tests/title_control_chars.rs b/crates/svg/tests/title_control_chars.rs
index 90c3d8c34..9057d8439 100644
--- a/crates/svg/tests/title_control_chars.rs
+++ b/crates/svg/tests/title_control_chars.rs
@@ -51,4 +51,7 @@ fn an_artboard_exported_alone_is_titled_after_it() {
// An unnamed artboard falls back to the document's title.
d.artboards[1].name = " ".into();
assert_eq!(title(&d, alone(Some(1))).as_deref(), Some("Icons"));
+ // So does one whose only characters can't appear in XML.
+ d.artboards[1].name = "\u{1}\u{2}".into();
+ assert_eq!(title(&d, alone(Some(1))).as_deref(), Some("Icons"));
}