diff --git a/crates/js/src/tests.rs b/crates/js/src/tests.rs index 07f04614d..01a436240 100644 --- a/crates/js/src/tests.rs +++ b/crates/js/src/tests.rs @@ -723,6 +723,21 @@ mod xfa_model { assert!(!o.effects.iter().any(|e| matches!(e, XfaEffect::SetPresence { som, .. } | XfaEffect::SetAccess { som, .. } if som.contains("qty")))); } + /// Past the effect cap, a value written to a field with no effect yet is left out of reads as + /// well as the effects; a field written again before the cap still takes its new value. + #[test] + fn a_value_past_the_effect_cap_is_left_out_of_reads_and_effects_alike() { + let o = go( + "price.rawValue = 1; for (var i = 0; i < 20000; i++) xfa.host.beep(); qty.rawValue = 9; price.rawValue = 3; qty.rawValue + ':' + price.rawValue", + "form1[0].page1[0]", + "click", + ); + assert_eq!(o.error, None, "{o:?}"); + assert_eq!(o.effects.len(), MAX_EFFECTS); + assert_eq!(o.result.as_deref(), Some("4:3")); + assert!(!o.effects.iter().any(|e| matches!(e, XfaEffect::SetValue { som, .. } if som.contains("qty")))); + } + #[test] fn urls_and_reset_lists_are_clipped_and_deduplicated() { let o = go( diff --git a/crates/js/src/xfa.rs b/crates/js/src/xfa.rs index 18013e001..8a60e8ba9 100644 --- a/crates/js/src/xfa.rs +++ b/crates/js/src/xfa.rs @@ -459,9 +459,9 @@ impl XHost { self.clipped_values += 1; } // The snapshot's copy and the effect's are charged together, before either is kept: - // past the byte budget the write is left out of both. + // past the byte budget or the effect cap the write is left out of both. let effect = XfaEffect::SetValue { som, value: text.clone() }; - if !self.room(text.len().saturating_add(payload(&effect))) { + if !self.reserve(&effect, text.len().saturating_add(payload(&effect))) { return true; } if let Some(n) = self.nodes.get_mut(i) {