From 50246683c35768de3fd9d70c7db74dc0e309a0cf Mon Sep 17 00:00:00 2001 From: Marco Arnulfo <103679419+marcoarnulfo@users.noreply.github.com> Date: Tue, 13 Oct 2026 10:38:24 +0200 Subject: [PATCH] DXF: read every ENTITIES section, not only the last (fixes #865) (#869) --- crates/io/src/dxf_read.rs | 3 ++- crates/io/tests/split_entities_section.rs | 19 +++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 crates/io/tests/split_entities_section.rs diff --git a/crates/io/src/dxf_read.rs b/crates/io/src/dxf_read.rs index 529fa83..f33ec4c 100644 --- a/crates/io/src/dxf_read.rs +++ b/crates/io/src/dxf_read.rs @@ -1603,7 +1603,8 @@ pub fn read(bytes: &[u8]) -> Result { } } } - "ENTITIES" => entities = parse_entities(&records(&s.tags), &mut d, &mut rx), + // A damaged file may split its entities over several ENTITIES sections (#865). + "ENTITIES" => entities.extend(parse_entities(&records(&s.tags), &mut d, &mut rx)), "OBJECTS" => { for (k, tg) in records(&s.tags) { objs.add(&k, &tg); diff --git a/crates/io/tests/split_entities_section.rs b/crates/io/tests/split_entities_section.rs new file mode 100644 index 0000000..6d89725 --- /dev/null +++ b/crates/io/tests/split_entities_section.rs @@ -0,0 +1,19 @@ +//! A damaged DXF can split its entities over several ENTITIES sections (with stray header +//! variables and ENDSECs between them, and no EOF). Every section is read, not just the last +//! one (#865). + +use cadcraft_doc::EntityKind; + +#[test] +fn entities_of_every_entities_section_are_read() { + let text = "0\nSECTION\n2\nENTITIES\n\ + 0\nTEXT\n8\n0\n10\n0\n20\n0\n40\n1\n1\nA\n\ + 0\nLINE\n8\n0\n10\n0\n20\n0\n11\n1\n21\n0\n\ + 0\nENDSEC\n9\n$EXTMIN\n10\n0\n20\n0\n0\nENDSEC\n\ + 0\nSECTION\n2\nENTITIES\n0\nLINE\n8\n0\n10\n0\n20\n1\n11\n1\n21\n1\n0\nENDSEC\n\ + 0\nSECTION\n2\nENTITIES\n0\nENDSEC\n"; + let d = cadcraft_io::read(text.as_bytes(), "t.dxf").unwrap(); + let lines = d.model.iter().filter(|e| matches!(e.kind, EntityKind::Line(_))).count(); + let texts = d.model.iter().filter(|e| matches!(e.kind, EntityKind::Text(_))).count(); + assert_eq!((lines, texts, d.model.len()), (2, 1, 3)); +}