Skip to content

fix(automation): XFA clicks and form edits return only the script output they produced - #4559

Open
dotCooCoo wants to merge 4 commits into
storytold:mainfrom
dotCooCoo:fix/automation-script-output-per-call
Open

dotCooCoo wants to merge 4 commits into
storytold:mainfrom
dotCooCoo:fix/automation-script-output-per-call

Conversation

@dotCooCoo

@dotCooCoo dotCooCoo commented Oct 24, 2026 •

Copy link
Copy Markdown
Contributor

What this changes

An XFA button click through run_javascript (js_run with field) and the form_set_script tool returned take_js_output, the document's whole waiting script output, as their own. In automation nothing else takes that output, so the next click or script change returned the alerts, console lines and errors of opening and of earlier edits as its own: after form_fill set a value that fails validation, a click on a button that shows "Hello 500" returned ["Quantity must be 100 or less", "Hello 500"]. Several tools that apply an edit, js_run among them when its script changes fields, also left their edit's output, such as the warnings for XFA data they could not write, in that output for the next click or form_set_script to report.

This pull request makes these changes:

  • Session::js_output_mark and Session::take_js_output_since take only what scripts added after a mark. What was waiting at the mark stays for take_js_output.
  • The XFA click path and form_set_script return only the output of their own edit.
  • The accessibility edits, js_set_document_script, form_set_actions, pdfa_convert, ocr_recognize, doc_compare_mark and form_detect_fields add the errors their edit produced, such as XFA values that could not be written to the form's data, to the result's warnings.
  • js_run without an XFA click adds the errors of applying its script's field changes to warnings, and returns the alerts, console lines and requests of the field scripts that those changes ran with the script's own. Its tool description says so.

This branch and #4551 change different lines and merge without conflicts. #4551's take_js_errors in doc_open and apply takes the errors that were waiting, and the tools here no longer leave their own behind for it. On the earlier head 8370c8a, with #4551 and #4166 merged in, cargo test -p pdfcraft-engine -p pdfcraft-automation passed, including #4166's form_fill_cannot_print_but_js_run_can, which reads the session's output after form_fill.

How you verified it

  • cargo fmt --check
  • clippy with -D warnings on the crates I changed
  • tests pass on the crates I changed
  • cargo xtask layers and cargo xtask assets (if you touched crate boundaries or any asset)

Tests. Each one fails on main:

  • an_xfa_click_returns_only_its_own_script_output (engine): a click after an open whose initialize script shows "opened" and throws returns only "Hello 2" and no error; the open's output stays. On main the alerts are ["opened", "Hello 2"].
  • an_xfa_click_through_js_run_does_not_return_an_earlier_fills_alerts (automation): after form_fill qty 500, a click returns ["Hello 500"] only.
  • form_set_script_does_not_return_an_earlier_fills_console_lines (automation): on main the result holds ["validated 7"] from the earlier fill.
  • edits_report_the_xfa_data_they_could_not_write_once (automation): js_set_document_script, form_set_actions and a js_run that sets a field each report the structured-content warning once in warnings, and form_set_script lists it once in errors. On main warnings is missing.
  • js_run_returns_the_output_of_the_calculations_its_changes_ran (automation): a js_run that sets a returns its own console line and the one that b's calculate script printed. On main only its own line is returned.

On Windows 11 (x86-64) with rustc 1.99.1, on b0a18a1, which has main at 20eebc1 merged in:

  • cargo fmt --all -- --check
  • cargo clippy -p pdfcraft-engine -p pdfcraft-automation --all-targets -- -D warnings
  • cargo test -p pdfcraft-engine -p pdfcraft-automation -p pdfcraft-ui-egui -p pdfcraft -p pdfcraft-cli: 11 test binaries, 2,622 passed, 15 ignored, and 1 failed: control::screenshots_of_window_and_region (pdfcraft-ui-egui) timed out waiting for the window to draw, and passed when run again on its own
  • cargo xtask layers, assets and parity

The full cargo xtask ci result is added once this pull request's gate check passes. cargo xtask ci passed its 10 steps on the earlier head 8370c8a on top of main at a7801dc (4,953 tests passed, 0 failed, 17 ignored).

Merge with main at dc943eeb (4b982964, test follow-up b4b3d4ec) checked with cargo fmt --check, clippy on pdfcraft-engine and pdfcraft-automation, and the five XFA script-output tests (5 passed).

The branch merges cleanly with main at dc943eeb.

Never-crash

  • No new unwrap/expect/panic!/unreachable!/todo! outside tests, unless it is
    provably infallible with a comment saying why
  • No indexing or slicing with input-derived positions (get, and strings only at char
    boundaries); checked or saturating arithmetic; allocations sized by input are capped;
    recursion is bounded
  • No unsafe
  • Any crash this fixes has a small synthetic regression test

This change fixes no crash.

Provenance

This is the part that cannot be undone after a merge, and the part a new contributor is
least likely to know about. Please read AGENTS.md §1 before adding any asset.

  • No asset from an Adobe product, and no Adobe icon recreated, traced or imitated
  • No font files committed here (they live in
    storytold/craft-fonts)
  • No GPL/AGPL code copied in — MuPDF, Ghostscript, Poppler, veraPDF and DSS may only be
    run as external oracle processes
  • Behaviour comes from the specification or black-box observation, not from reading
    another implementation's source
  • Every new asset has an ATTRIBUTION.toml entry and cargo xtask assets passes

Anything a reviewer should look at first

The direct edit tools now return warnings when an XFA form's data could not be written. On such a form, the click's own edit writes the data too, so a click still reports that warning as its error.

Summary by CodeRabbit

  • Bug Fixes
    • Automation responses now include warnings generated during accessibility edits, form changes, PDF/A conversion, text recognition, difference marking, and form-field detection. Failed edits continue to return errors.
    • JavaScript results now include alerts, console messages, and viewer requests triggered by the operation, including field calculations. Output from earlier actions is kept separate, reducing unrelated messages in results. XFA content that cannot be written to form data is reported as a warning.

…put they produced

An XFA button click through run_javascript and the form_set_script tool
returned the document's whole waiting script output as their own. In
automation nothing else takes that output, so the next click or script
change returned the alerts, console lines and errors of opening and of
earlier edits as its own. Several tools that apply an edit (the
accessibility edits, js_set_document_script, form_set_actions,
pdfa_convert, ocr_recognize, doc_compare_mark, form_detect_fields, and
js_run when its script changes fields) also left their edit's output,
such as the warnings for XFA data they could not write, in that output.

Session::js_output_mark and take_js_output_since take only what scripts
added after a mark, and leave the rest for take_js_output. The click
path and form_set_script use them. The edit tools add their edit's
errors to the result's warnings, and js_run also returns the alerts,
console lines and requests of the field scripts that its changes ran.
@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review.

Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between b0a18a1 and b4b3d4e.

Files selected for processing: 5
  • crates/automation/src/a11y/form_tools.rs
  • crates/automation/src/tools.rs
  • crates/automation/tests/it/automation.rs
  • crates/engine/src/js.rs
  • crates/engine/src/tests.rs

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.

Walkthrough

JavaScript output is scoped to individual operations. Automation responses include errors generated during edits and execution. js_run also returns alerts, console lines, and requests from its execution. Tests cover output separation, XFA button clicks, and structured-content write failures.

Changes: JavaScript Output Handling

Layer / File(s) Summary
Scoped JavaScript output capture
crates/engine/src/js.rs, crates/engine/src/tests.rs
The engine marks current JavaScript output and takes output added after that mark. XFA button clicks use this scoped capture. Tests check that click output excludes earlier output and that failed clicks do not repeat errors.
Automation output and warning responses
crates/automation/src/a11y.rs, crates/automation/src/a11y/documents.rs, crates/automation/src/a11y/form_tools.rs, crates/automation/src/a11y/ocr.rs, crates/automation/src/tools.rs, crates/automation/tests/it/automation.rs
Automation operations attach newly generated errors to responses as warnings. js_run includes alerts, console entries, and requests generated during its execution. The integration tests cover output scoping and warnings from values that cannot be written to structured XFA data.

Priority: Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Suggested reviewers: aiongg, mtlcl410

Merge Risk: Minimal · up to b4b3d

The reviewed output-scoping and warning changes have no remaining identified merge-blocking issue. Merge after normal checks.

Security architecture risk: Low · up to b4b3d

The change improves attribution of script output to the operation that produced it. Newly returned script requests remain response data in the reviewed code; whether external clients execute those requests with separate authorization is not established.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — The demonstrated exposure change is additional script-originated response data for the selected document, not demonstrated access to another document or service. External clients' handling of those newly returned request records remains outside the inspected scope.

Security Findings and Attack Paths

  • observed — The changed js_run response path serializes script requests rather than executing them. The focused source comparison therefore establishes broader request visibility, but not a new in-repository request-execution attack path.

Trust Boundaries and Controls

  • observed — The pre-existing execution controls remain: run_javascript rejects disabled JavaScript and read-only documents, edit application checks document permissions, and ordinary field-script output filters Save As and panel requests before queuing them. The PR changes capture and serialization rather than these controls.

Hardening Proposals

  • proposed — For integrations that execute returned navigation, submission, printing, or similar requests, define them as untrusted document output requiring separate client authorization. This is an integration safeguard, not an observed missing control in this repository.
Pre-merge checks: Passed 4 · Inconclusive 1

Failed Failed checks: 1 inconclusive

Check name Status Explanation Resolution
Docstring Coverage Inconclusive Docstring coverage is 29.41% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documenta… Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main change: XFA clicks and form edits now return only the script output they produced.
Description check Passed The description is detailed and covers the behavior change, verification commands, regression tests, safety checks, provenance, and reviewer focus. It omits the template's separate Security and Parity…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description is detailed and covers the behavior change, verification commands, regression tests, safety checks, provenance, and reviewer focus. It omits the template's separate Security and Parity sections, but the available information is sufficient and the relevant parity command is documented under verification.

Full details: Docstring Coverage

Explanation

Docstring coverage is 29.41% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff with cyclomatic complexity of at least 2. Documentation-only edits and deletions within surviving functions are included; unchanged diff context and fully deleted functions are excluded. Analyzed 17 functions across 7 files. (1 skipped: 1 too large.)

Resolution

Write docstrings for the functions missing them to satisfy the coverage threshold.

Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@FredApps FredApps left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. XFA clicks and form edits now return only the script output they produced: the automation tools take a mark of the document's script output before each edit and take out only what was added after it (errors become a warnings list on the result, merged into an existing one), the JS output type gets mark/split_off helpers that clamp to the current length, and the click path and js_run use the same mark so output from opening or earlier edits stays queued. I read the whole non-test diff; the gate and SonarCloud pass at 8370c8a. I read the code and the CI results; I did not run the app.

@dotCooCoo

Copy link
Copy Markdown
Contributor Author

Merged main at 20eebc1 into this branch (b0a18a1). The one conflict came from main splitting crates/automation/src/a11y.rs into a11y/documents.rs, a11y/form_tools.rs and a11y/ocr.rs; the branch's changes to js_run, form_set_script, js_set_document_script, form_detect_fields, form_set_actions, pdfa_convert, doc_compare_mark and ocr_recognize now sit in those files, and apply_with_warnings and with_warnings stay in a11y.rs.

The branch merges cleanly with main at 20eebc1. Checks on b0a18a1:

  • cargo fmt --all -- --check
  • cargo clippy -p pdfcraft-engine -p pdfcraft-automation --all-targets -- -D warnings
  • cargo test -p pdfcraft-engine -p pdfcraft-automation -p pdfcraft-ui-egui -p pdfcraft -p pdfcraft-cli: 11 test binaries, 2,622 passed, 15 ignored; control::screenshots_of_window_and_region timed out waiting for the window to draw and passed when run again on its own
  • cargo xtask layers, assets and parity

The full cargo xtask ci result is added to the body once this pull request's gate check passes.

dotCooCoo added a commit to dotCooCoo/pdfcraft that referenced this pull request Oct 28, 2026
Taken through storytold#4559's merge of main at 20eebc1. The page_enhance_camera change moves to dispatch.rs, where main moved Automation::call.
main now reports each js_run alert as an object with its message, title,
icon and buttons, so the XFA click test compares against that object.
engine/src/tests.rs keeps main's bytes, CRLF lines included, with the
XFA click test added.
@dotCooCoo

Copy link
Copy Markdown
Contributor Author

Merged main (dc943eeb) to clear the conflict, as 4b982964, with a follow-up commit b4b3d4ec. Both conflicts were in crates/automation. In a11y/form_tools.rs, main added doc comments and alert_json on js_run, and this branch reads only the output added since a mark. In tools.rs, main added the text_styles and bookmark_from_text_styles tools and edited several tool descriptions, and this branch edited the js_run description. The resolution keeps both sides. b4b3d4ec changes this branch's XFA click test to expect the alert objects that js_run now returns, and keeps crates/engine/src/tests.rs byte for byte as on main apart from the added test. cargo fmt --check, cargo clippy -p pdfcraft-engine -p pdfcraft-automation --all-targets -- -D warnings and the five XFA script-output tests (1 in pdfcraft-engine, 4 in pdfcraft-automation) pass on b4b3d4ec. The branch now merges cleanly with main.

dotCooCoo added a commit to dotCooCoo/pdfcraft that referenced this pull request Oct 29, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants