有界 XFA FormCalc 与 JavaScript

HotPDF 在扁平化表单时求值 XFA 计算脚本,具有始终可用的有界 FormCalc 路径和更广泛的 QuickJS 路径,后者在应用程序显式启用之前保持禁用

扩展 FormCalc

FormCalc 表达式支持算术、字符串、布尔、比较运算符、短路 And、Or 和 Not,以及惰性 If(condition, whenTrue, whenFalse) 分支

Sum、Avg、Min、Max 和 Count 接受重复数字数据,如 rows[*].amount;只求值 If 的选定分支,因此未使用的无效分支不会拒绝计算

嵌套调用可以组合数值、字符串和节点集结果,确定性地支持 At、Choose、Concat、LTrim、RTrim、Str、Stuff、Null、Sign、Exp、Log、Sin、Cos、Tan、Deg2Rad、Rad2Deg、Within 和 Oneof

用户自定义函数、循环、赋值、locale picture 子句和网络函数仍在原生子集之外,会 fail closed

InstanceAdd(name, count) 和 InstanceRemove(name, index) 只在参数和操作预算验证后通过 OnXFAInstanceAction 分发

可选 JavaScript

在 ApplyXFAAsAcroForm 或 FlattenLoadedXFA 之前将 THotPDF.XFAJavaScriptEnabled 设置为 True,以运行其 contentType 选择 JavaScript 的脚本

运行时支持正常的 JavaScript 控制流和原生类型化数组,如 Float64Array,但不接收文件、进程、网络、浏览器或应用程序对象;fetch、XMLHttpRequest、WebSocket、require、process 和 Deno 不可用

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;

脚本上下文

JavaScript 接收可变的 this.rawValue、event.value 和冻结的 xfa 门面

预算与遥测

THPDFXFAFormScriptBudgets 约束脚本字节、FormCalc 操作、经过的时间、表达式深度、重复数组项、值字节、实例操作、JavaScript 内存、JavaScript 栈使用和中断检查

栈预算提供递归边界,而时间和中断预算停止不终止的循环;越过任何边界的脚本失败关闭并将诊断追加到 XFAFlattenWarnings

XFAFlattenScriptsEvaluated、XFAFlattenScriptsRejected 和 XFAFlattenInstanceOperations 报告最新的扁平化阶段

直接运行时集成

扩展的 HPDFXFAFlatten 重载直接接受 TXFAFormScriptOptions 和 TXFAFormInstanceAction;分配 TXFAFormScriptOptions.JavaScriptEvaluator 以适配静态 QuickJS 绑定或另一个应用程序拥有的求值器,同时保留相同的包装器和预算

参见 TXFAFormScriptOptions、TXFAFormScriptLimits、THPDFXFAFormScriptBudgets 和 THPDFXFAInstanceAction