Ограниченные FormCalc и JavaScript в XFA

HotPDF выполняет calculate-скрипты XFA во время flattening формы: путь FormCalc ограничен и доступен всегда, а более широкий путь через QuickJS остаётся выключенным, пока приложение его явно не включит

Расширенный FormCalc

Выражения FormCalc поддерживают арифметику, строки, булевы значения, операторы сравнения, short-circuit And, Or и Not, а также ленивую ветку If(condition, whenTrue, whenFalse)

Sum, Avg, Min, Max и Count принимают смесь скалярных аргументов и node-set SOM с путями rooted, direct, indexed, wildcard или descendant вроде $record.rows[*].amount; вычисляется только выбранная ветка If, поэтому невалидная неиспользуемая ветка не отвергает расчёт

Вложенные вызовы могут комбинировать числовые, строковые и node-set результаты, с детерминированной поддержкой At, Choose, Concat, LTrim, RTrim, Str, Stuff, Null, Sign, Exp, Log, Sin, Cos, Tan, Deg2Rad, Rad2Deg, Within и Oneof

Пользовательские функции, циклы, присваивание, locale picture clauses и сетевые функции остаются за пределами нативного подмножества и завершаются отказом (fail closed)

InstanceAdd(name, count) и InstanceRemove(name, index) диспетчеризуются через OnXFAInstanceAction только после проверки аргументов и бюджета операций

Опциональный JavaScript

Установите THotPDF.XFAJavaScriptEnabled в True перед ApplyXFAAsAcroForm или FlattenLoadedXFA, чтобы выполнять скрипты, у которых contentType выбирает JavaScript

Runtime поддерживает обычный control flow 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 отчитываются о последнем проходе flattening

Прямая интеграция runtime

Расширенная перегрузка HPDFXFAFlatten принимает TXFAFormScriptOptions и TXFAFormInstanceAction напрямую; присвойте TXFAFormScriptOptions.JavaScriptEvaluator, чтобы адаптировать статический QuickJS binding или другой evaluator во владении приложения, сохранив ту же обёртку и бюджеты

См. TXFAFormScriptOptions, TXFAFormScriptLimits, THPDFXFAFormScriptBudgets и THPDFXFAInstanceAction