Omit AcroForm field options with an undefined value#1742
Conversation
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.
|
Should be fixed in main by f331b16 Can you run against main to test? |
|
Thanks for the pointer! I ran the branch against current f331b16 only normalizes the Object.keys(VALUE_MAP).forEach((key) => {
if (key in options) {
options[VALUE_MAP[key]] = options[key] ?? '';
delete options[key];
}
});Any other option set to So This PR drops any The branch is already on top of current |
Fixes #1735.
Problem
Passing a field option whose value is
undefinedtodoc.form*()causes that key to be serialized as the literal tokenundefined:A name key followed by the bare token
undefinedis not a valid PDF object. Lenient viewers tolerate it, but strict parsers reject it — the issue reports iText RUPS throwingNullPointerException("object is null") on such a field.#1738 ("Normalize nullish AcroForm text values to empty strings") addressed only the mapped
value/defaultValuekeys viaVALUE_MAP. Any other option passed asundefinedstill leaks into the dictionary, so the broader issue #1735 remains.Fix
Drop entries whose value is
undefinedin_fieldDict, right before the dictionary is returned. A field created with an extraundefinedoption then serializes byte-for-byte identically to one created without that option at all. Defined options (including those legitimately set to falsy values like0,false, or"") are untouched.Tests
Added a unit test (
tests/unit/acroform.spec.js) asserting that a field built with{ CustomKey: undefined }contains noundefinedtoken and matches the output of the same field built with{}./CustomKey undefined).