From 876c96223549f9678b1bb35c178db41091211514 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Fri, 31 May 2019 20:44:24 +0200 Subject: [PATCH] Ignore Annotations with too large border `width`s, to prevent the `annotationLayer` from rendering it over the surrounding document (bug 1552113) The border `width` will instead fallback to the default value of `1`, rather than ignoring it altoghether, to also ensure that e.g. `LinkAnnotation`s become clickable as intended. Fixes https://bugzilla.mozilla.org/show_bug.cgi?id=1552113 --- src/core/annotation.js | 36 ++++++++++++++--- test/pdfs/.gitignore | 1 + test/pdfs/bug1552113.pdf | 86 ++++++++++++++++++++++++++++++++++++++++ test/test_manifest.json | 9 +++++ 4 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 test/pdfs/bug1552113.pdf diff --git a/src/core/annotation.js b/src/core/annotation.js index 5a2bb9448..985cf1c8a 100644 --- a/src/core/annotation.js +++ b/src/core/annotation.js @@ -16,7 +16,8 @@ import { AnnotationBorderStyleType, AnnotationFieldFlag, AnnotationFlag, - AnnotationType, isString, OPS, stringToBytes, stringToPDFString, Util, warn + AnnotationType, assert, isString, OPS, stringToBytes, stringToPDFString, Util, + warn } from '../shared/util'; import { Catalog, FileSpec, ObjectLoader } from './obj'; import { Dict, isDict, isName, isRef, isStream } from './primitives'; @@ -361,6 +362,11 @@ class Annotation { * @param {Dict} borderStyle - The border style dictionary */ setBorderStyle(borderStyle) { + if (typeof PDFJSDev === 'undefined' || + PDFJSDev.test('!PRODUCTION || TESTING')) { + assert(this.rectangle, 'setRectangle must have been called previously.'); + } + this.borderStyle = new AnnotationBorderStyle(); if (!isDict(borderStyle)) { return; @@ -370,7 +376,7 @@ class Annotation { let dictType = dict.get('Type'); if (!dictType || isName(dictType, 'Border')) { - this.borderStyle.setWidth(dict.get('W')); + this.borderStyle.setWidth(dict.get('W'), this.rectangle); this.borderStyle.setStyle(dict.get('S')); this.borderStyle.setDashArray(dict.getArray('D')); } @@ -379,7 +385,7 @@ class Annotation { if (Array.isArray(array) && array.length >= 3) { this.borderStyle.setHorizontalCornerRadius(array[0]); this.borderStyle.setVerticalCornerRadius(array[1]); - this.borderStyle.setWidth(array[2]); + this.borderStyle.setWidth(array[2], this.rectangle); if (array.length === 4) { // Dash array available this.borderStyle.setDashArray(array[3]); @@ -497,9 +503,16 @@ class AnnotationBorderStyle { * * @public * @memberof AnnotationBorderStyle - * @param {integer} width - The width + * @param {integer} width - The width. + * @param {Array} rect - The annotation `Rect` entry. */ - setWidth(width) { + setWidth(width, rect = [0, 0, 0, 0]) { + if (typeof PDFJSDev === 'undefined' || + PDFJSDev.test('!PRODUCTION || TESTING')) { + assert(Array.isArray(rect) && rect.length === 4, + 'A valid `rect` parameter must be provided.'); + } + // Some corrupt PDF generators may provide the width as a `Name`, // rather than as a number (fixes issue 10385). if (isName(width)) { @@ -507,6 +520,19 @@ class AnnotationBorderStyle { return; } if (Number.isInteger(width)) { + if (width > 0) { + const maxWidth = (rect[2] - rect[0]) / 2; + const maxHeight = (rect[3] - rect[1]) / 2; + + // Ignore large `width`s, since they lead to the Annotation overflowing + // the size set by the `Rect` entry thus causing the `annotationLayer` + // to render it over the surrounding document (fixes bug1552113.pdf). + if ((maxWidth > 0 && maxHeight > 0) && + (width > maxWidth || width > maxHeight)) { + warn(`AnnotationBorderStyle.setWidth - ignoring width: ${width}`); + width = 1; + } + } this.width = width; } } diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index b704c9682..769026c76 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -96,6 +96,7 @@ !bug1245391_reduced.pdf !bug1252420.pdf !bug1513120_reduced.pdf +!bug1552113.pdf !issue9949.pdf !bug1308536.pdf !bug1337429.pdf diff --git a/test/pdfs/bug1552113.pdf b/test/pdfs/bug1552113.pdf new file mode 100644 index 000000000..cc4dd45c0 --- /dev/null +++ b/test/pdfs/bug1552113.pdf @@ -0,0 +1,86 @@ +%PDF-1.7 +%âãÏÓ +1 0 obj +<< +/Pages 2 0 R +/Type /Catalog +>> +endobj +2 0 obj +<< +/Kids [3 0 R] +/Type /Pages +/Count 1 +>> +endobj +3 0 obj +<< +/Parent 2 0 R +/Annots [4 0 R] +/Resources +<< +/Font +<< +/F1 5 0 R +>> +>> +/MediaBox [0 0 250 50] +/Type /Page +/Contents 6 0 R +>> +endobj +4 0 obj +<< +/Border [0 0 112] +/Subtype /Link +/C [0 0 1] +/A +<< +/URI (http://www.example.org) +/Type /Action +/S /URI +>> +/Type /Annot +/Rect [5 25 155 45] +>> +endobj +5 0 obj +<< +/BaseFont /Times-Roman +/Subtype /Type1 +/Type /Font +/Encoding /WinAnsiEncoding +>> +endobj +6 0 obj +<< +/Length 111 +>> +stream +BT +10 30 TD +/F1 14 Tf +(http://www.example.org/) Tj +0 -20 Td +(Bug 1552113 - this text should be visible.) Tj +ET + +endstream +endobj xref +0 7 +0000000000 65535 f +0000000015 00000 n +0000000066 00000 n +0000000125 00000 n +0000000270 00000 n +0000000432 00000 n +0000000533 00000 n +trailer + +<< +/Root 1 0 R +/Size 7 +>> +startxref +697 +%%EOF diff --git a/test/test_manifest.json b/test/test_manifest.json index ecf7234d5..c7d7ab37a 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -680,6 +680,15 @@ "annotations": true, "about": "Annotation with (unsupported) file:// URL." }, + { "id": "bug1552113", + "file": "pdfs/bug1552113.pdf", + "md5": "dafb7ba1328e8deaab2e3619c94bf974", + "link": false, + "rounds": 1, + "type": "eq", + "annotations": true, + "about": "Annotation with (ridiculously) large border width." + }, { "id": "issue4934", "file": "pdfs/issue4934.pdf", "md5": "6099da44f677702ae65a648b51a2226d",