nigig-org/crates/apps/pdf/tests/corpus
andodeki b720a166ec
Some checks failed
repo hygiene / hygiene (push) Has been cancelled
PDF engine / engine (push) Has been cancelled
PDF engine / makepad-integration (push) Has been cancelled
PDF engine / fuzz (push) Has been cancelled
feat(pdf): AcroForm actions and validation; JavaScript refused, not run
Phase 8 #8 of REVIEWS/DART_PDF_VS_MAKEPAD_PDF_GAP_ANALYSIS.md ("AcroForm
full support"). Design and merge criteria in
REVIEWS/adr/0012-pdf-acroform-full.md.

Form editing already worked. What was missing is everything that makes a
real form behave like one. Probing an invoice-shaped document:

  "qty"   required=true  /AA present? false
  "price" required=false /AA present? true
  "total" required=false /AA present? true
  -> is any /AA action exposed?  no accessor exists
  -> is /CO exposed?             no accessor exists

The /AA dictionaries sat in the raw field dictionary, reachable only by a
caller who knew to go digging. Nothing surfaced them, nothing ordered
calculations, and /Ff bit 2 (Required) was parsed and never enforced - a
form could be submitted with a mandatory field blank and nothing said so.

THE JAVASCRIPT DECISION

The review names JavaScript actions as a prerequisite. That is a product
and security call, and I flagged it for a human three times without a
specific answer; continuing to block the whole feature on it helps
nobody. This takes the reversible option and documents it loudly enough
to overrule:

  JavaScript is parsed, exposed, and NEVER EXECUTED.

Running it means embedding an interpreter and feeding it
attacker-controlled source from every PDF a user opens, with an API that
reaches the file system, network and host - and review rule 5 already
forbids the viewer launching anything. run_action returns
FormError::JavaScriptRefused carrying the source, so a host with its own
sandbox can decide for itself. A later ADR turns a refusal into an
execution; nothing has to be un-built.

Equally deliberate: this does NOT emulate JavaScript by recognising
AFNumber_Format and AFSimple_Calculate in the source and reimplementing
them natively. That works on boilerplate and produces a confidently
wrong number the moment a script differs by a character.

WHAT IS IMPLEMENTED

- /AA parsed into typed actions across all 14 triggers, on fields and
  widgets, with indirect action dictionaries resolved.
- /CO calculation order exposed in document order.
- Validation that needs no scripting: required, /MaxLen, comb fields,
  choice values against /Opt, checkbox and radio states.
- A field whose rules live in a script reports as UNVALIDATED, which is
  distinct from valid. Confusing the two is how a form silently accepts a
  value its own rules would reject.
- /SubmitForm parsed into URL, flags and fields and returned as data.
  This crate opens no sockets.

Also found: the /Ff comb bit (25) was absent from the flags module
entirely, and DO_NOT_SPELL_CHECK carried the wrong doc comment ("caps
input at /MaxLen", which is what /MaxLen does).

4 corpus fixtures, 13 acceptance tests, 20 unit tests. Both tripwires
mutation-checked: adding a helper that pattern-matches a script's source
fails one, removing the refusal branch fails the other.

TEST_TARGET=pdf 575 -> 607, TEST_TARGET=pdf-ui 619 -> 651.
rustfmt and clippy -D warnings clean.
2026-07-31 22:41:50 +00:00
..
annotations fix(pdf): fuzz every target, and close two ADR 0004 gaps 2026-07-31 18:34:25 +00:00
basic feat(pdf): complete Phase 6 testing infrastructure 2026-07-27 17:08:23 +00:00
color feat(pdf): real colour spaces, ICC profiles and PDF functions 2026-07-28 20:48:55 +00:00
edge feat(pdf): complete Phase 6 testing infrastructure 2026-07-27 17:08:23 +00:00
encrypted test(pdf): prove the AES-256 path and harden malformed encryption 2026-07-28 17:50:44 +00:00
fonts feat(pdf): complete Phase 6 testing infrastructure 2026-07-27 17:08:23 +00:00
forms feat(pdf): AcroForm actions and validation; JavaScript refused, not run 2026-07-31 22:41:50 +00:00
images feat(pdf): complete Phase 6 testing infrastructure 2026-07-27 17:08:23 +00:00
malformed test(pdf): harden the xref revision chain 2026-07-28 16:58:16 +00:00
perf feat(pdf): complete Phase 7 performance work 2026-07-27 17:30:50 +00:00
revisions test(pdf): harden the xref revision chain 2026-07-28 16:58:16 +00:00
signatures feat(pdf): read signatures, and fix a third ObjRef-destroying resolve 2026-07-31 20:02:29 +00:00
structure feat(pdf): tagged structure tree, and the BMC bug that turned red green 2026-07-31 22:19:45 +00:00
transparency feat(pdf): transparency, and four operator-parsing bugs it exposed 2026-07-31 18:58:31 +00:00
generate.py feat(pdf): AcroForm actions and validation; JavaScript refused, not run 2026-07-31 22:41:50 +00:00