Merge pull request #21575 from calixteman/fix/signature-fields-with-widget-kids

Fix signature fields with widget children
This commit is contained in:
Tim van der Meij 2026-07-16 20:08:35 +02:00 committed by GitHub
commit f472cb081c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 44 additions and 12 deletions

View File

@ -2009,20 +2009,19 @@ class PDFDocument {
if (!(field instanceof Dict)) {
continue;
}
if (isName(field.get("FT"), "Sig")) {
const sigDict = this.xref.fetchIfRef(field.get("V"));
if (sigDict instanceof Dict) {
const parsed = this.#parseSignatureDict(field, sigDict, fieldRef);
if (parsed) {
out.push(parsed);
}
}
}
if (field.has("Kids")) {
// A terminal field can have Widget annotations as children, so its
// own signature must be collected before walking the field tree.
this.#collectSignatureFields(field.get("Kids"), out, visitedRefs);
continue;
}
if (!isName(field.get("FT"), "Sig")) {
continue;
}
const sigDict = this.xref.fetchIfRef(field.get("V"));
if (!(sigDict instanceof Dict)) {
continue;
}
const parsed = this.#parseSignatureDict(field, sigDict, fieldRef);
if (parsed) {
out.push(parsed);
}
}
}

View File

@ -312,6 +312,39 @@ describe("document", function () {
expect(signatures[0].signerName).toEqual("John Smith");
});
it("extracts signature fields with Widget children", async function () {
const acroForm = new Dict();
acroForm.set("SigFlags", 3);
const sigRef = Ref.get(33, 0);
const sigFieldRef = Ref.get(34, 0);
const widgetRef = Ref.get(35, 0);
const sigDict = makeSigDict({
byteRange: [0, 50, 100, 150],
name: "Alice",
});
const sigField = makeSigField({ T: "sig_alice", sigRef });
sigField.set("Kids", [widgetRef]);
const widget = new Dict();
widget.set("Subtype", Name.get("Widget"));
widget.set("Parent", sigFieldRef);
const xref = new XRefMock([
{ ref: sigRef, data: sigDict },
{ ref: sigFieldRef, data: sigField },
{ ref: widgetRef, data: widget },
]);
acroForm.set("Fields", [sigFieldRef]);
const pdfDocument = getDocument(acroForm, xref);
const signatures = await pdfDocument.signatures;
expect(signatures.length).toEqual(1);
expect(signatures[0].fieldName).toEqual("sig_alice");
expect(signatures[0].signerName).toEqual("Alice");
});
it("skips signatures with malformed ByteRange", async function () {
const acroForm = new Dict();
acroForm.set("SigFlags", 3);