Merge pull request #3794 from Silvertree2010/fix/3572-audit-dxf-import-nested-inserts

Bound DXF import work for nested inserts that produce no nodes
This commit is contained in:
BFlat
2026-10-24 02:01:28 +07:00
committed by GitHub
2 changed files with 29 additions and 0 deletions
+11
View File
@@ -23,6 +23,8 @@ const PT_PER_MM: f64 = 72.0 / 25.4;
const THINNEST: f64 = 0.25;
/// The most objects an import makes.
const MAX_NODES: usize = 2_000_000;
/// The most block visits (one per insert copy) an import makes, whatever they produce.
const MAX_VISITS: usize = 10_000_000;
/// How far from the origin art may lie (points): the canvas.
pub(crate) const MAX_EXTENT: f64 = 4.0e6;
@@ -63,6 +65,7 @@ pub(crate) struct Build<'d, 'a> {
/// Lineweights are multiplied by this.
lw_scale: f64,
nodes: usize,
visits: usize,
warnings: Vec<String>,
}
@@ -118,6 +121,7 @@ impl<'d, 'a> Build<'d, 'a> {
symbol_map: Affine::IDENTITY,
lw_scale: 1.0,
nodes: 0,
visits: 0,
warnings: vec![],
}
}
@@ -557,6 +561,13 @@ impl<'d, 'a> Build<'d, 'a> {
/// The art of block `name` drawn by `map`, as one object.
fn art(&mut self, name: &str, map: Affine, inh: &Inherit, depth: u32) -> Option<Node> {
self.visits += 1;
if self.visits > MAX_VISITS {
if self.visits == MAX_VISITS + 1 {
self.warn(TOO_MANY);
}
return None;
}
let items = self.block(name)?;
if !self.enter(name, depth) {
return None;
+18
View File
@@ -799,6 +799,24 @@ fn array_inserts_attributes_and_dimensions() {
assert_eq!(bounds(&leaves(&doc)[0]).width(), 50.0);
}
#[test]
fn nested_array_inserts_of_nothing_stop_at_the_work_budget() {
let block = |name: &'static str, inner: Option<&'static str>| {
let mut b = vec![(0, "BLOCK"), (2, name), (70, "1"), (10, "0"), (20, "0")];
if let Some(i) = inner {
b.extend([(0, "INSERT"), (2, i), (10, "0"), (20, "0"), (70, "300"), (44, "1")]);
}
b.push((0, "ENDBLK"));
b
};
let mut blocks = block("*A", Some("*B"));
blocks.extend(block("*B", Some("*C")));
blocks.extend(block("*C", None));
let top = [(0, "INSERT"), (2, "*A"), (10, "0"), (20, "0"), (70, "300"), (44, "1")];
let r = open(&drawing(&[], &[], &blocks, &top), &points());
assert!(r.warnings.iter().any(|w| w.contains("more than")), "{:?}", r.warnings);
}
#[test]
fn blocks_inside_themselves_are_left_out_without_hanging() {
let blocks = [