From 668d8f777e6ee7a73e610be30fbdd69303473ba3 Mon Sep 17 00:00:00 2001 From: aiongg Date: Thu, 22 Oct 2026 20:08:33 +0000 Subject: [PATCH] fix(xfa): every drawn subform instance spends the layout budget A positioned root draws its children instead of flowing them, so nested repeating subforms under it multiplied their instances without spending the measurement budget that flowed instances spend. Drawing a subform instance spends it too. --- crates/xfa/src/layout.rs | 4 ++++ crates/xfa/src/tests.rs | 10 ++++++++++ 2 files changed, 14 insertions(+) diff --git a/crates/xfa/src/layout.rs b/crates/xfa/src/layout.rs index b4d331255..db1f2bfcb 100644 --- a/crates/xfa/src/layout.rs +++ b/crates/xfa/src/layout.rs @@ -1318,6 +1318,10 @@ impl Layouter<'_> { Ok(()) } Node::Subform(s) => { + // Every drawn instance spends budget, as a flowed one does, so nested repeats that + // place nothing still stop. + self.measures.set(self.measures.get().saturating_add(1)); + self.check_measures()?; if let Some(b) = &s.common.border { self.draw_border(b, rect)?; } diff --git a/crates/xfa/src/tests.rs b/crates/xfa/src/tests.rs index 03a7d2c5a..c41070974 100644 --- a/crates/xfa/src/tests.rs +++ b/crates/xfa/src/tests.rs @@ -433,6 +433,16 @@ fn a_packet_stream_listed_many_times_is_read_once() { assert_eq!(p.xdp.matches(""; + let nest = + |n: usize| format!("", level.repeat(n), "".repeat(n)); + assert!(matches!(layout_xml(&nest(4)), Err(XfaError::TooLarge(_)))); + assert!(layout_xml(&nest(3)).is_ok()); +} + #[test] fn the_packets_can_be_one_stream_or_named_parts() { // Named parts, with the template split from the rest.