Skip to content

Omit AcroForm field options with an undefined value#1742

Open
chatman-media wants to merge 1 commit into
foliojs:masterfrom
chatman-media:fix/acroform-omit-undefined-field-options
Open

Omit AcroForm field options with an undefined value#1742
chatman-media wants to merge 1 commit into
foliojs:masterfrom
chatman-media:fix/acroform-omit-undefined-field-options

Conversation

@chatman-media

Copy link
Copy Markdown

Fixes #1735.

Problem

Passing a field option whose value is undefined to doc.form*() causes that key to be serialized as the literal token undefined:

doc.formText("demofield", 10, 692, 200, 40, { someOption: undefined });
10 0 obj
<<
/someOption undefined   <-- invalid: a name key with no value object
/FT /Tx
/T (demofield)
...
>>
endobj

A name key followed by the bare token undefined is not a valid PDF object. Lenient viewers tolerate it, but strict parsers reject it — the issue reports iText RUPS throwing NullPointerException ("object is null") on such a field.

#1738 ("Normalize nullish AcroForm text values to empty strings") addressed only the mapped value/defaultValue keys via VALUE_MAP. Any other option passed as undefined still leaks into the dictionary, so the broader issue #1735 remains.

Fix

Drop entries whose value is undefined in _fieldDict, right before the dictionary is returned. A field created with an extra undefined option then serializes byte-for-byte identically to one created without that option at all. Defined options (including those legitimately set to falsy values like 0, false, or "") are untouched.

Tests

Added a unit test (tests/unit/acroform.spec.js) asserting that a field built with { CustomKey: undefined } contains no undefined token and matches the output of the same field built with {}.

  • Fails without the fix (the dictionary contains /CustomKey undefined).
  • Passes with the fix.
  • Full unit suite: 318 passing. ESLint and Prettier clean.

Passing a field option whose value is `undefined` to `doc.form*()`
serialized the key as the literal token `undefined` (e.g.
`/SomeKey undefined`), producing an invalid PDF object that strict
parsers (PDFium, iText) reject. foliojs#1738 only handled the mapped
`value`/`defaultValue` keys; any other undefined option still leaked.

Drop entries with an undefined value in `_fieldDict` so such a field
serializes identically to one created without the option. Fixes foliojs#1735.
@blikblum

Copy link
Copy Markdown
Member

Should be fixed in main by f331b16

Can you run against main to test?

@chatman-media

Copy link
Copy Markdown
Author

Thanks for the pointer! I ran the branch against current master (which includes f331b16). The commit fixes the mapped text values, but a more general case still leaks.

f331b16 only normalizes the VALUE_MAP keys (value/defaultValue/V, /DV):

Object.keys(VALUE_MAP).forEach((key) => {
  if (key in options) {
    options[VALUE_MAP[key]] = options[key] ?? '';
    delete options[key];
  }
});

Any other option set to undefined is still serialized as the literal token undefined. My regression test options with an undefined value are omitted (tests/unit/acroform.spec.js) covers this — it passes { CustomKey: undefined } to formText. Running just that test on master (i.e. with f331b16 but without this PR's change) fails:

AssertionError: expected '10 0 obj<<\n/CustomKey undefined\n/FT…' not to match /undefined/

10 0 obj<<
/CustomKey undefined
/FT /Tx
/T (demofield)
...

So /CustomKey undefined is an invalid object that strict parsers (PDFium, iText) reject — the same class of bug as #1738, just not limited to value/defaultValue.

This PR drops any undefined-valued entry in _fieldDict before the dictionary is built, so such a field serializes byte-for-byte like one created without the option. Defined falsy values (0, false, '') are untouched.

The branch is already on top of current master (no rebase needed), and the full suite is green (53 files / 371 tests). Happy to adjust the approach if you'd prefer it handled elsewhere.

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.

Acroforms: Setting a field option to undefined results in an invalid PDF

2 participants