Bounded XFA FormCalc and JavaScript

HotPDF evaluates XFA calculate scripts whilst flattening a form, with an always-available bounded FormCalc path and a broader QuickJS path that remains disabled until the application explicitly switches it on

Extended FormCalc

FormCalc expressions support arithmetic, strings, booleans, comparison operators, short-circuit And, Or and Not, plus the lazy If(condition, whenTrue, whenFalse) branch

Sum, Avg, Min, Max and Count accept mixed scalar and SOM node-set arguments using rooted, direct, indexed, wildcard or descendant paths such as $record.rows[*].amount; only the selected branch of If is evaluated, so an unused invalid branch does not reject the calculation

Nested calls can combine numeric, string and node-set results, with deterministic support for At, Choose, Concat, LTrim, RTrim, Str, Stuff, Null, Sign, Exp, Log, Sin, Cos, Tan, Deg2Rad, Rad2Deg, Within and Oneof

User-defined functions, loops, assignment, locale picture clauses and network functions remain outside the native subset and fail closed

InstanceAdd(name, count) and InstanceRemove(name, index) dispatch through OnXFAInstanceAction only after argument and operation-budget validation

Optional JavaScript

Set THotPDF.XFAJavaScriptEnabled to True before ApplyXFAAsAcroForm or FlattenLoadedXFA to run scripts whose contentType picks JavaScript

The runtime supports normal JavaScript control flow and native typed arrays such as Float64Array, but receives no file, process, network, browser or application object; fetch, XMLHttpRequest, WebSocket, require, process and Deno are unavailable

var
  Budgets: THPDFXFAFormScriptBudgets;
begin
  Budgets := THPDFXFAFormScriptBudgets.Default;
  Budgets.MaxElapsedMilliseconds := 100;
  Budgets.JavaScriptMemoryBytes := 8 * 1024 * 1024;
  PDF.XFAFormScriptBudgets := Budgets;
  PDF.XFAJavaScriptEnabled := True;
  PDF.OnXFAInstanceAction := HandleXFAInstanceAction;
  PDF.ApplyXFAAsAcroForm(XDPBytes, False);
end;

Script context

JavaScript receives a mutable this.rawValue, an event.value and a frozen xfa facade

Budgets and telemetry

THPDFXFAFormScriptBudgets bounds script bytes, FormCalc operations, elapsed time, expression depth, repeated-array items, value bytes, instance operations, JavaScript memory, JavaScript stack use and interrupt checks

The stack budget provides the recursion boundary, whilst the time and interrupt budgets stop non-terminating loops; scripts that cross any boundary fail closed and append a diagnostic to XFAFlattenWarnings

XFAFlattenScriptsEvaluated, XFAFlattenScriptsRejected and XFAFlattenInstanceOperations report the latest flattening pass

Direct runtime integration

The extended HPDFXFAFlatten overload accepts TXFAFormScriptOptions and TXFAFormInstanceAction directly; assign TXFAFormScriptOptions.JavaScriptEvaluator to adapt the static QuickJS binding or another application-owned evaluator whilst retaining the same wrapper and budgets

See TXFAFormScriptOptions, TXFAFormScriptLimits, THPDFXFAFormScriptBudgets and THPDFXFAInstanceAction