diff --git a/crates/svg/src/import/files.rs b/crates/svg/src/import/files.rs index 722d043d4..b6d488c9e 100644 --- a/crates/svg/src/import/files.rs +++ b/crates/svg/src/import/files.rs @@ -287,8 +287,10 @@ impl Files { if depth::xml_deeper_than(text, left) { return leave_out(&self.too_deep, true); } - let height = depth::height(&super::parse(text).ok()?, left); - let Some(height) = height else { return leave_out(&self.too_deep, true) }; + let xml = super::parse(text).ok()?; + let Some(height) = depth::height(&xml, left) else { return leave_out(&self.too_deep, true) }; + // usvg's parser would overflow on it, as on the SVG holding it (`import`). + super::convolve_matrices_ok(&xml).ok()?; self.note_text(text); self.depth.store(used + height, Ordering::Relaxed); let tree = usvg::Tree::from_data_nested(text.as_bytes(), opts); @@ -462,6 +464,22 @@ mod tests { assert_eq!(read(MAX_ELEMENT_DEPTH, 0), (false, 1)); } + /// An SVG image with a `feConvolveMatrix` order usvg's multiply overflows is left out before + /// usvg reads it, as the SVG holding it would be refused. + #[test] + fn svg_images_with_an_overflowing_convolve_order_are_left_out() { + let read = |order: &str| { + let svg = format!( + r#""# + ); + let files = Files::default(); + let resolver = files.resolver(1); + matches!((resolver.resolve_data)("image/svg+xml", Arc::new(svg.into_bytes()), &usvg::Options::default()), Some(ImageKind::SVG(_))) + }; + assert!(!read("2147483647")); + assert!(read("1")); + } + #[test] fn the_placeholder_is_a_png() { let png = marker().unwrap();