From 8a2b8f4bdf214c7f3e3ac3ea43a1ed35c78a5d24 Mon Sep 17 00:00:00 2001 From: midasmatterhorn <248507632+midasmatterhorn@users.noreply.github.com> Date: Thu, 15 Oct 2026 17:43:04 +0300 Subject: [PATCH] io: the four symbol tables honour the same record cap as their peers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LAYER, LTYPE, STYLE and DIMSTYLE records were appended with no cap while the VIEW, UCS and VPORT arms of the same loop guard at MAX_OBJECTS — so a hostile DXF could grow the layer table (each record found by a linear case-insensitive name scan) without bound. The same guard now applies to all seven table kinds. Behaviour is unchanged for every legal drawing: no drawing approaches a million table records, so no regression test can reach the cap at unit scale (the same reason the peer guards shipped without one). The quadratic cost of the name lookups themselves is a separate, larger change (resolving table names through a map while reading) deliberately left to the maintainers. --- crates/io/src/dxf_read.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/crates/io/src/dxf_read.rs b/crates/io/src/dxf_read.rs index 7615bc569..705a7cc08 100644 --- a/crates/io/src/dxf_read.rs +++ b/crates/io/src/dxf_read.rs @@ -1422,7 +1422,7 @@ fn tables(tags: &[Tag], d: &mut Drawing, rx: &mut Rx) { match kind.as_str() { "LAYER" => { let name = t.s(2).unwrap_or_default(); - if name.is_empty() { + if name.is_empty() || d.layers.len() >= MAX_OBJECTS { continue; } let aci = t.i(62).unwrap_or(7); @@ -1459,7 +1459,7 @@ fn tables(tags: &[Tag], d: &mut Drawing, rx: &mut Rx) { } "LTYPE" => { let name = t.s(2).unwrap_or_default(); - if name.is_empty() || d.linetype(&name).is_some() { + if name.is_empty() || d.linetype(&name).is_some() || d.linetypes.len() >= MAX_OBJECTS { continue; } let pattern = ltype_pattern(&tg, <ype_styles); @@ -1467,7 +1467,7 @@ fn tables(tags: &[Tag], d: &mut Drawing, rx: &mut Rx) { } "STYLE" => { let name = t.s(2).unwrap_or_default(); - if name.is_empty() { + if name.is_empty() || d.text_styles.len() >= MAX_OBJECTS { continue; } // 70 bit 4: vertical; 71 bits 2/4: backwards / upside down. @@ -1549,7 +1549,7 @@ fn tables(tags: &[Tag], d: &mut Drawing, rx: &mut Rx) { } "DIMSTYLE" => { let name = t.s(2).unwrap_or_default(); - if name.is_empty() { + if name.is_empty() || d.dim_styles.len() >= MAX_OBJECTS { continue; } // Every variable with a DIMSTYLE group code; values the style can't take are