diff --git a/crates/svg/src/import/importer.rs b/crates/svg/src/import/importer.rs
index 5b96ea5bd..2e3bc14c2 100644
--- a/crates/svg/src/import/importer.rs
+++ b/crates/svg/src/import/importer.rs
@@ -664,7 +664,7 @@ impl Importer {
return None;
}
if self.nested_svg_images >= crate::MAX_NESTED_SVG_IMAGES {
- self.error = Some(SvgError::TooLarge(self.max_nodes));
+ self.error = Some(SvgError::TooManyImages(crate::MAX_NESTED_SVG_IMAGES));
return None;
}
self.nested_svg_images += 1;
@@ -682,3 +682,47 @@ impl Importer {
art
}
}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+ use crate::import::files::Files;
+ use crate::import::text::TextSlots;
+ use std::collections::{HashMap, HashSet};
+ use vectorcraft_doc::Document;
+
+ #[test]
+ fn svg_image_cap_sets_too_many_images_error() {
+ let mut im = Importer {
+ doc: Document::new(100.0, 100.0),
+ warnings: vec![],
+ mask_flags: HashMap::new(),
+ links: HashMap::new(),
+ slots: TextSlots::default(),
+ patterns: HashMap::new(),
+ midpoints: HashMap::new(),
+ labels: HashMap::new(),
+ hidden: HashSet::new(),
+ uses: HashMap::new(),
+ symbols: HashMap::new(),
+ blends: HashMap::new(),
+ files: Files::default(),
+ non_scaling: HashSet::new(),
+ data: HashMap::new(),
+ events: HashMap::new(),
+ foreign: HashMap::new(),
+ sublayers: HashSet::new(),
+ sublayer_groups: HashSet::new(),
+ screen: 1.0,
+ converted_nodes: 0,
+ max_nodes: 1000,
+ error: None,
+ nested_svg_images: crate::MAX_NESTED_SVG_IMAGES,
+ };
+ let tree = usvg::Tree::from_str(r#""#, &usvg::Options::default()).unwrap();
+ let res = im.svg_image(&tree, Affine::IDENTITY);
+ assert!(res.is_none());
+ assert!(matches!(im.error, Some(SvgError::TooManyImages(crate::MAX_NESTED_SVG_IMAGES))));
+ assert_eq!(im.error.unwrap().to_string(), "the SVG expands to more than 256 nested SVG images");
+ }
+}
diff --git a/crates/svg/src/import/text.rs b/crates/svg/src/import/text.rs
index a922a70e3..0e26fc524 100644
--- a/crates/svg/src/import/text.rs
+++ b/crates/svg/src/import/text.rs
@@ -162,6 +162,7 @@ pub(super) struct PendingText {
}
/// The texts [`prepare`] replaced, by placeholder index.
+#[derive(Default)]
pub(super) struct TextSlots {
prefix: String,
pub texts: Vec,
diff --git a/crates/svg/src/lib.rs b/crates/svg/src/lib.rs
index 7a0c5ddf9..ccc154a38 100644
--- a/crates/svg/src/lib.rs
+++ b/crates/svg/src/lib.rs
@@ -347,6 +347,10 @@ pub enum SvgError {
/// nested-image expansion bombs, #3564).
#[error("the SVG expands to more than {0} objects")]
TooLarge(usize),
+ /// The SVG expands to more nested SVG images than the reader takes (a guard against
+ /// nested-image expansion bombs, #3564).
+ #[error("the SVG expands to more than {0} nested SVG images")]
+ TooManyImages(usize),
}
/// Export a document as an SVG string (linked images are not returned: see [`export_full`]).