From 04bb6d6f278ae0239d6c035bbbc0ea309e2c5592 Mon Sep 17 00:00:00 2001 From: bflatastic Date: Tue, 13 Oct 2026 11:38:40 +0700 Subject: [PATCH] SVG import: an Inkscape page whose box can't be placed is skipped --- crates/svg/src/import.rs | 6 ++++-- crates/svg/tests/import_details.rs | 9 +++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/crates/svg/src/import.rs b/crates/svg/src/import.rs index c800f871..289693e8 100644 --- a/crates/svg/src/import.rs +++ b/crates/svg/src/import.rs @@ -296,14 +296,16 @@ fn inkscape_pages(xml: &roxmltree::Document, user: Affine) -> Option 0.0 && h > 0.0).then(|| (p, Rect::new(x, y, x + w, y + h))) + // A box too large to add up or to place (1e308 wide) is no page. + let r = user.transform_rect_bbox(Rect::new(x, y, x + w, y + h)); + (w > 0.0 && h > 0.0 && r.is_finite()).then_some((p, r)) }) .take(1000) .enumerate() .map(|(i, (p, r))| vectorcraft_doc::Artboard { id: i as u32 + 1, name: p.attribute((INKSCAPE, "label")).filter(|l| !l.trim().is_empty()).map_or_else(|| format!("Artboard {}", i + 1), str::to_string), - rect: user.transform_rect_bbox(r), + rect: r, show_center_mark: false, show_cross_hairs: false, }) diff --git a/crates/svg/tests/import_details.rs b/crates/svg/tests/import_details.rs index a4127bbd..9929aff9 100644 --- a/crates/svg/tests/import_details.rs +++ b/crates/svg/tests/import_details.rs @@ -240,6 +240,15 @@ fn inkscape_pages_become_artboards() { let d = import_with(svg, &ImportOptions::default()).unwrap().0; let b: Vec<(String, Rect)> = d.artboards.iter().map(|a| (a.name.clone(), a.rect)).collect(); assert_eq!(b, vec![("Front".to_string(), Rect::new(0.0, 0.0, 200.0, 200.0)), ("Artboard 2".to_string(), Rect::new(240.0, 0.0, 360.0, 300.0))]); + // Hostile boxes (too large to add up, not numbers, negative) are no pages, and at most 1,000 are read. + let pages = r#""#.to_string() + + &r#""#.repeat(1500); + let hostile = format!( + r#"{pages}"# + ); + let d = import_with(&hostile, &ImportOptions::default()).unwrap().0; + assert_eq!(d.artboards.len(), 1000); + assert!(d.artboards.iter().all(|a| a.rect == Rect::new(0.0, 0.0, 10.0, 10.0)), "{:?}", d.artboards.first()); // A file without pages keeps its one artboard. let d = import_with(&svg_doc(), &ImportOptions::default()).unwrap().0; assert_eq!(d.artboards.len(), 1);