Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display widget signature #13214

Merged
merged 1 commit into from
Apr 10, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions l10n/en-US/chrome.properties
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
# Chrome notification bar messages and buttons
unsupported_feature=This PDF document might not be displayed correctly.
unsupported_feature_forms=This PDF document contains forms. The filling of form fields is not supported.
unsupported_feature_signatures=This PDF document contains digital signatures. Validation of signatures is not supported.
calixteman marked this conversation as resolved.
Show resolved Hide resolved
open_with_different_viewer=Open With Different Viewer
open_with_different_viewer.accessKey=o
39 changes: 22 additions & 17 deletions src/core/annotation.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ class AnnotationFactory {
return new ButtonWidgetAnnotation(parameters);
case "Ch":
return new ChoiceWidgetAnnotation(parameters);
case "Sig":
return new SignatureWidgetAnnotation(parameters);
}
warn(
`Unimplemented widget field type "${fieldType}", ` +
Expand Down Expand Up @@ -1151,15 +1153,6 @@ class WidgetAnnotation extends Annotation {

data.readOnly = this.hasFieldFlag(AnnotationFieldFlag.READONLY);
data.hidden = this._hasFlag(data.annotationFlags, AnnotationFlag.HIDDEN);

// Hide signatures because we cannot validate them, and unset the fieldValue
// since it's (most likely) a `Dict` which is non-serializable and will thus
// cause errors when sending annotations to the main-thread (issue 10347).
if (data.fieldType === "Sig") {
data.fieldValue = null;
this.setFlags(AnnotationFlag.HIDDEN);
data.hidden = true;
}
}

/**
Expand Down Expand Up @@ -1201,7 +1194,7 @@ class WidgetAnnotation extends Annotation {
getOperatorList(evaluator, task, renderForms, annotationStorage) {
// Do not render form elements on the canvas when interactive forms are
// enabled. The display layer is responsible for rendering them instead.
if (renderForms) {
if (renderForms && !(this instanceof SignatureWidgetAnnotation)) {
return Promise.resolve(new OperatorList());
}

Expand Down Expand Up @@ -1600,13 +1593,6 @@ class WidgetAnnotation extends Annotation {
}

getFieldObject() {
if (this.data.fieldType === "Sig") {
return {
id: this.data.id,
value: null,
type: "signature",
};
}
return null;
}
}
Expand Down Expand Up @@ -2203,6 +2189,25 @@ class ChoiceWidgetAnnotation extends WidgetAnnotation {
}
}

class SignatureWidgetAnnotation extends WidgetAnnotation {
constructor(params) {
super(params);

// Unset the fieldValue since it's (most likely) a `Dict` which is
// non-serializable and will thus cause errors when sending annotations
// to the main-thread (issue 10347).
this.data.fieldValue = null;
}

getFieldObject() {
return {
id: this.data.id,
value: null,
type: "signature",
};
}
}

class TextAnnotation extends MarkupAnnotation {
constructor(parameters) {
const DEFAULT_ICON_SIZE = 22; // px
Expand Down
12 changes: 10 additions & 2 deletions src/core/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -828,7 +828,12 @@ class PDFDocument {
}

get formInfo() {
const formInfo = { hasFields: false, hasAcroForm: false, hasXfa: false };
const formInfo = {
hasFields: false,
hasAcroForm: false,
hasXfa: false,
hasSignatures: false,
};
const acroForm = this.catalog.acroForm;
if (!acroForm) {
return shadow(this, "formInfo", formInfo);
Expand All @@ -854,9 +859,11 @@ class PDFDocument {
// the first bit of the `SigFlags` integer (see Table 219 in the
// specification).
const sigFlags = acroForm.get("SigFlags");
const hasSignatures = !!(sigFlags & 0x1);
const hasOnlyDocumentSignatures =
!!(sigFlags & 0x1) && this._hasOnlyDocumentSignatures(fields);
hasSignatures && this._hasOnlyDocumentSignatures(fields);
formInfo.hasAcroForm = hasFields && !hasOnlyDocumentSignatures;
formInfo.hasSignatures = hasSignatures;
} catch (ex) {
if (ex instanceof MissingDataException) {
throw ex;
Expand Down Expand Up @@ -894,6 +901,7 @@ class PDFDocument {
IsAcroFormPresent: this.formInfo.hasAcroForm,
IsXFAPresent: this.formInfo.hasXfa,
IsCollectionPresent: !!this.catalog.collection,
IsSignaturesPresent: this.formInfo.hasSignatures,
};

let infoDict;
Expand Down
1 change: 1 addition & 0 deletions src/shared/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ const UNSUPPORTED_FEATURES = {
unknown: "unknown",
forms: "forms",
javaScript: "javaScript",
signatures: "signatures",
smask: "smask",
shadingPattern: "shadingPattern",
/** @deprecated unused */
Expand Down
1 change: 1 addition & 0 deletions test/pdfs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
!issue9458.pdf
!issue9655_reduced.pdf
!issue9915_reduced.pdf
!bug854315.pdf
!issue9940.pdf
!issue10388_reduced.pdf
!issue10438_reduced.pdf
Expand Down
Binary file added test/pdfs/bug854315.pdf
Binary file not shown.
6 changes: 6 additions & 0 deletions test/test_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,12 @@
"rounds": 1,
"type": "load"
},
{ "id": "bug854315",
"file": "pdfs/bug854315.pdf",
"md5": "675754c07f71c068d2997905a5456f05",
"rounds": 1,
"type": "eq"
},
timvandermeij marked this conversation as resolved.
Show resolved Hide resolved
{ "id": "bug868745",
"file": "pdfs/bug868745.pdf",
"md5": "86111ea5097dd7daffcdea891ad1b348",
Expand Down
3 changes: 3 additions & 0 deletions test/unit/api_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,7 @@ describe("api", function () {
expect(info.IsAcroFormPresent).toEqual(false);
expect(info.IsXFAPresent).toEqual(false);
expect(info.IsCollectionPresent).toEqual(false);
expect(info.IsSignaturesPresent).toEqual(false);
calixteman marked this conversation as resolved.
Show resolved Hide resolved

expect(metadata instanceof Metadata).toEqual(true);
expect(metadata.get("dc:title")).toEqual("Basic API Test");
Expand Down Expand Up @@ -1254,6 +1255,7 @@ describe("api", function () {
expect(info.IsAcroFormPresent).toEqual(false);
expect(info.IsXFAPresent).toEqual(false);
expect(info.IsCollectionPresent).toEqual(false);
expect(info.IsSignaturesPresent).toEqual(false);

expect(metadata).toEqual(null);
expect(contentDispositionFilename).toEqual(null);
Expand Down Expand Up @@ -1282,6 +1284,7 @@ describe("api", function () {
expect(info.IsAcroFormPresent).toEqual(false);
expect(info.IsXFAPresent).toEqual(false);
expect(info.IsCollectionPresent).toEqual(false);
expect(info.IsSignaturesPresent).toEqual(false);

expect(metadata).toEqual(null);
expect(contentDispositionFilename).toEqual(null);
Expand Down
9 changes: 9 additions & 0 deletions test/unit/document_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ describe("document", function () {
const pdfDocument = getDocument(null);
expect(pdfDocument.formInfo).toEqual({
hasAcroForm: false,
hasSignatures: false,
hasXfa: false,
hasFields: false,
});
Expand All @@ -90,6 +91,7 @@ describe("document", function () {
let pdfDocument = getDocument(acroForm);
expect(pdfDocument.formInfo).toEqual({
hasAcroForm: false,
hasSignatures: false,
hasXfa: false,
hasFields: false,
});
Expand All @@ -98,6 +100,7 @@ describe("document", function () {
pdfDocument = getDocument(acroForm);
expect(pdfDocument.formInfo).toEqual({
hasAcroForm: false,
hasSignatures: false,
hasXfa: true,
hasFields: false,
});
Expand All @@ -106,6 +109,7 @@ describe("document", function () {
pdfDocument = getDocument(acroForm);
expect(pdfDocument.formInfo).toEqual({
hasAcroForm: false,
hasSignatures: false,
hasXfa: false,
hasFields: false,
});
Expand All @@ -114,6 +118,7 @@ describe("document", function () {
pdfDocument = getDocument(acroForm);
expect(pdfDocument.formInfo).toEqual({
hasAcroForm: false,
hasSignatures: false,
hasXfa: true,
hasFields: false,
});
Expand All @@ -127,6 +132,7 @@ describe("document", function () {
let pdfDocument = getDocument(acroForm);
expect(pdfDocument.formInfo).toEqual({
hasAcroForm: false,
hasSignatures: false,
hasXfa: false,
hasFields: false,
});
Expand All @@ -135,6 +141,7 @@ describe("document", function () {
pdfDocument = getDocument(acroForm);
expect(pdfDocument.formInfo).toEqual({
hasAcroForm: true,
hasSignatures: false,
hasXfa: false,
hasFields: true,
});
Expand All @@ -146,6 +153,7 @@ describe("document", function () {
pdfDocument = getDocument(acroForm);
expect(pdfDocument.formInfo).toEqual({
hasAcroForm: true,
hasSignatures: false,
hasXfa: false,
hasFields: true,
});
Expand All @@ -169,6 +177,7 @@ describe("document", function () {
pdfDocument = getDocument(acroForm, xref);
expect(pdfDocument.formInfo).toEqual({
hasAcroForm: false,
hasSignatures: true,
hasXfa: false,
hasFields: true,
});
Expand Down
5 changes: 5 additions & 0 deletions web/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -1583,6 +1583,11 @@ const PDFViewerApplication = {
this._delayedFallback(UNSUPPORTED_FEATURES.forms);
}

if (info.IsSignaturesPresent) {
console.warn("Warning: Digital signatures validation is not supported");
this.fallback(UNSUPPORTED_FEATURES.signatures);
}

// Telemetry labels must be C++ variable friendly.
let versionId = "other";
if (KNOWN_VERSIONS.includes(info.PDFFormatVersion)) {
Expand Down