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.
This commit is contained in:
aiongg
2026-10-22 20:08:33 +00:00
parent a887405ea1
commit 668d8f777e
2 changed files with 14 additions and 0 deletions
+4
View File
@@ -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)?;
}
+10
View File
@@ -433,6 +433,16 @@ fn a_packet_stream_listed_many_times_is_read_once() {
assert_eq!(p.xdp.matches("<template").count(), 1);
}
#[test]
fn empty_repeating_subforms_drawn_in_a_positioned_root_spend_the_layout_budget() {
// The same four levels inside a positioned root are drawn, not flowed.
let level = "<subform layout=\"tb\"><occur initial=\"50\" max=\"-1\"/>";
let nest =
|n: usize| format!("<template><subform><subform layout=\"tb\">{}{}</subform></subform></template>", level.repeat(n), "</subform>".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.