fix(forms): script streams share one decode budget per reading

Each field action and document-script entry decoded its /JS stream
with a fresh 1 GiB allowance and kept its own copy, so many fields or
name-tree pairs naming one compressed stream retained gigabytes. A
reading of the fields, one field's actions, and the document scripts
each share a 64 MiB DecodeBudget for their script streams.
This commit is contained in:
aiongg
2026-10-22 16:57:55 +00:00
parent 92ab0e932d
commit bb8ea65ffd
4 changed files with 81 additions and 21 deletions
+2 -1
View File
@@ -176,6 +176,7 @@ pub fn document_scripts_named(doc: &Document) -> Vec<(String, String)> {
let Some(names) = cat.as_dict().and_then(|c| c.get(b"Names")).map(|n| doc.resolve(n)) else { return Vec::new() };
let Some(tree) = names.as_dict().and_then(|n| n.get(b"JavaScript")).cloned() else { return Vec::new() };
let mut out: Vec<(String, String)> = Vec::new();
let mut scripts = crate::script_budget();
// Kids stay unresolved on the stack, and each node is read once: a node listed many times,
// or among its own kids, must not multiply the work.
let mut stack = vec![tree];
@@ -203,7 +204,7 @@ pub fn document_scripts_named(doc: &Document) -> Vec<(String, String)> {
Object::String(s) => s.to_text(),
_ => continue,
};
if let Some(js) = crate::script(doc, v) {
if let Some(js) = crate::script(doc, v, &mut scripts) {
out.push((key, js));
}
}