diff --git a/src/core/annotation.js b/src/core/annotation.js index 38ca66a66..6540e0841 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -74,13 +74,14 @@ AnnotationFactory.prototype = /** @lends AnnotationFactory.prototype */ { // Determine the annotation's subtype. var subtype = dict.get('Subtype'); - subtype = isName(subtype) ? subtype.name : ''; + subtype = isName(subtype) ? subtype.name : null; // Return the right annotation object based on the subtype and field type. var parameters = { xref: xref, dict: dict, - ref: ref + ref: ref, + subtype: subtype, }; switch (subtype) { @@ -116,8 +117,12 @@ AnnotationFactory.prototype = /** @lends AnnotationFactory.prototype */ { return new FileAttachmentAnnotation(parameters); default: - warn('Unimplemented annotation type "' + subtype + '", ' + - 'falling back to base annotation'); + if (!subtype) { + warn('Annotation is missing the required /Subtype.'); + } else { + warn('Unimplemented annotation type "' + subtype + '", ' + + 'falling back to base annotation.'); + } return new Annotation(parameters); } } @@ -181,7 +186,7 @@ var Annotation = (function AnnotationClosure() { // Expose public properties using a data object. this.data = {}; this.data.id = params.ref.toString(); - this.data.subtype = dict.get('Subtype').name; + this.data.subtype = params.subtype; this.data.annotationFlags = this.flags; this.data.rect = this.rectangle; this.data.color = this.color; diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 7e0a5f6a2..6cbda038d 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -31,6 +31,7 @@ !issue7403.pdf !issue7426.pdf !issue7439.pdf +!issue7446.pdf !issue7492.pdf !filled-background.pdf !ArabicCIDTrueType.pdf diff --git a/test/pdfs/issue7446.pdf b/test/pdfs/issue7446.pdf new file mode 100644 index 000000000..7def26265 --- /dev/null +++ b/test/pdfs/issue7446.pdf @@ -0,0 +1,51 @@ +%PDF-1.7 +%%μῦ + +1 0 obj +<> +endobj + +2 0 obj +<> +endobj + +3 0 obj +<>>>/Contents 5 0 R>> +endobj + +4 0 obj +<> +endobj + +5 0 obj +<> +stream +BT +10 10 TD +/F1 12 Tf +(Renders even with a broken annotation) Tj +ET + +endstream +endobj + +6 0 obj +<> +endobj + +xref +0 7 +0000000000 65536 f +0000000018 00000 n +0000000064 00000 n +0000000138 00000 n +0000000243 00000 n +0000000309 00000 n +0000000426 00000 n + +trailer +<> + +startxref +518 +%%EOF diff --git a/test/test_manifest.json b/test/test_manifest.json index 4a1604a3d..8816c1706 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -1131,6 +1131,14 @@ "link": false, "type": "eq" }, + { "id": "issue7446", + "file": "pdfs/issue7446.pdf", + "md5": "1b5bdd8a806e6ab9eda7c1c707b75fc6", + "rounds": 1, + "link": false, + "type": "load", + "about": "Annotation without the required /Subtype." + }, { "id": "issue7492-eq", "file": "pdfs/issue7492.pdf", "md5": "7b0b28919c1088a2a5a0aeedbaa4c3ca", diff --git a/test/unit/annotation_layer_spec.js b/test/unit/annotation_layer_spec.js index c7f773b94..ea8cd02eb 100644 --- a/test/unit/annotation_layer_spec.js +++ b/test/unit/annotation_layer_spec.js @@ -26,11 +26,35 @@ describe('Annotation layer', function() { annotationFactory = null; }); + describe('AnnotationFactory', function () { + it('should handle missing /Subtype', function () { + var annotationDict = new Dict(); + annotationDict.set('Type', Name.get('Annot')); + + var xrefMock = new XrefMock([annotationDict]); + var annotationRef = new Ref(1, 0); + + var annotation = annotationFactory.create(xrefMock, annotationRef); + var data = annotation.data; + expect(data.annotationType).toBeUndefined(); + }); + }); + describe('Annotation', function() { + var dict, ref; + + beforeAll(function (done) { + dict = new Dict(); + ref = new Ref(1, 0); + done(); + }); + + afterAll(function () { + dict = ref = null; + }); + it('should set and get flags', function() { - var dict = new Dict(); - dict.set('Subtype', ''); - var annotation = new Annotation({ dict: dict, ref: 0 }); + var annotation = new Annotation({ dict: dict, ref: ref }); annotation.setFlags(13); expect(annotation.hasFlag(AnnotationFlag.INVISIBLE)).toEqual(true); @@ -40,81 +64,63 @@ describe('Annotation layer', function() { }); it('should be viewable and not printable by default', function() { - var dict = new Dict(); - dict.set('Subtype', ''); - var annotation = new Annotation({ dict: dict, ref: 0 }); + var annotation = new Annotation({ dict: dict, ref: ref }); expect(annotation.viewable).toEqual(true); expect(annotation.printable).toEqual(false); }); it('should set and get a valid rectangle', function() { - var dict = new Dict(); - dict.set('Subtype', ''); - var annotation = new Annotation({ dict: dict, ref: 0 }); + var annotation = new Annotation({ dict: dict, ref: ref }); annotation.setRectangle([117, 694, 164.298, 720]); expect(annotation.rectangle).toEqual([117, 694, 164.298, 720]); }); it('should not set and get an invalid rectangle', function() { - var dict = new Dict(); - dict.set('Subtype', ''); - var annotation = new Annotation({ dict: dict, ref: 0 }); + var annotation = new Annotation({ dict: dict, ref: ref }); annotation.setRectangle([117, 694, 164.298]); expect(annotation.rectangle).toEqual([0, 0, 0, 0]); }); it('should reject a color if it is not an array', function() { - var dict = new Dict(); - dict.set('Subtype', ''); - var annotation = new Annotation({ dict: dict, ref: 0 }); + var annotation = new Annotation({ dict: dict, ref: ref }); annotation.setColor('red'); expect(annotation.color).toEqual(new Uint8Array([0, 0, 0])); }); it('should set and get a transparent color', function() { - var dict = new Dict(); - dict.set('Subtype', ''); - var annotation = new Annotation({ dict: dict, ref: 0 }); + var annotation = new Annotation({ dict: dict, ref: ref }); annotation.setColor([]); expect(annotation.color).toEqual(null); }); it('should set and get a grayscale color', function() { - var dict = new Dict(); - dict.set('Subtype', ''); - var annotation = new Annotation({ dict: dict, ref: 0 }); + var annotation = new Annotation({ dict: dict, ref: ref }); annotation.setColor([0.4]); expect(annotation.color).toEqual(new Uint8Array([102, 102, 102])); }); it('should set and get an RGB color', function() { - var dict = new Dict(); - dict.set('Subtype', ''); - var annotation = new Annotation({ dict: dict, ref: 0 }); + var annotation = new Annotation({ dict: dict, ref: ref }); annotation.setColor([0, 0, 1]); expect(annotation.color).toEqual(new Uint8Array([0, 0, 255])); }); it('should set and get a CMYK color', function() { - var dict = new Dict(); - dict.set('Subtype', ''); - var annotation = new Annotation({ dict: dict, ref: 0 }); + var annotation = new Annotation({ dict: dict, ref: ref }); annotation.setColor([0.1, 0.92, 0.84, 0.02]); expect(annotation.color).toEqual(new Uint8Array([233, 59, 47])); }); it('should not set and get an invalid color', function() { - var dict = new Dict(); - dict.set('Subtype', ''); - var annotation = new Annotation({ dict: dict, ref: 0 }); + var annotation = new Annotation({ dict: dict, ref: ref }); annotation.setColor([0.4, 0.6]); expect(annotation.color).toEqual(new Uint8Array([0, 0, 0]));