From 97c10e9c08eaaf994252702e88f3897b56990e6e Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Mon, 4 Jan 2016 21:33:41 +0100 Subject: [PATCH] Strip `null` (\x00) characters from the URLs in LinkAnnotations (issue 6832) Apparently some PDF files can have annotations with `URI` entries ending with `null` characters, thus breaking the links. To handle this edge-case of bad PDFs, this patch moves the already existing utility function from `ui_utils.js` into `util.js`, in order to fix those URLs. Fixes 6832. --- src/display/annotation_layer.js | 4 +++- src/shared/util.js | 11 +++++++++++ test/unit/ui_utils_spec.js | 14 +------------- test/unit/util_spec.js | 15 ++++++++++++++- web/pdf_attachment_view.js | 4 ++-- web/pdf_outline_view.js | 4 ++-- web/ui_utils.js | 6 ------ 7 files changed, 33 insertions(+), 25 deletions(-) diff --git a/src/display/annotation_layer.js b/src/display/annotation_layer.js index 196a0e325..cd4fffd5c 100644 --- a/src/display/annotation_layer.js +++ b/src/display/annotation_layer.js @@ -33,6 +33,7 @@ var AnnotationType = sharedUtil.AnnotationType; var Util = sharedUtil.Util; var isExternalLinkTargetSet = sharedUtil.isExternalLinkTargetSet; var LinkTargetStringMap = sharedUtil.LinkTargetStringMap; +var removeNullCharacters = sharedUtil.removeNullCharacters; var warn = sharedUtil.warn; var CustomStyle = displayDOMUtils.CustomStyle; @@ -232,7 +233,8 @@ var LinkAnnotationElement = (function LinkAnnotationElementClosure() { this.container.className = 'linkAnnotation'; var link = document.createElement('a'); - link.href = link.title = this.data.url || ''; + link.href = link.title = (this.data.url ? + removeNullCharacters(this.data.url) : ''); if (this.data.url && isExternalLinkTargetSet()) { link.target = LinkTargetStringMap[PDFJS.externalLinkTarget]; diff --git a/src/shared/util.js b/src/shared/util.js index baf3ee70d..3efe137d5 100644 --- a/src/shared/util.js +++ b/src/shared/util.js @@ -504,6 +504,16 @@ var XRefParseException = (function XRefParseExceptionClosure() { return XRefParseException; })(); +var NullCharactersRegExp = /\x00/g; + +function removeNullCharacters(str) { + if (typeof str !== 'string') { + warn('The argument for removeNullCharacters must be a string.'); + return str; + } + return str.replace(NullCharactersRegExp, ''); +} +PDFJS.removeNullCharacters = removeNullCharacters; function bytesToString(bytes) { assert(bytes !== null && typeof bytes === 'object' && @@ -1690,6 +1700,7 @@ exports.log2 = log2; exports.readInt8 = readInt8; exports.readUint16 = readUint16; exports.readUint32 = readUint32; +exports.removeNullCharacters = removeNullCharacters; exports.shadow = shadow; exports.string32 = string32; exports.stringToBytes = stringToBytes; diff --git a/test/unit/ui_utils_spec.js b/test/unit/ui_utils_spec.js index b6f4a9cf0..597199aba 100644 --- a/test/unit/ui_utils_spec.js +++ b/test/unit/ui_utils_spec.js @@ -1,20 +1,8 @@ -/* globals expect, it, describe, binarySearchFirstItem, removeNullCharacters */ +/* globals expect, it, describe, binarySearchFirstItem */ 'use strict'; describe('ui_utils', function() { - describe('removeNullCharacters', function() { - it('should not modify string without null characters', function() { - var str = 'string without null chars'; - expect(removeNullCharacters(str)).toEqual('string without null chars'); - }); - - it('should modify string with null characters', function() { - var str = 'string\x00With\x00Null\x00Chars'; - expect(removeNullCharacters(str)).toEqual('stringWithNullChars'); - }); - }); - describe('binary search', function() { function isTrue(boolean) { return boolean; diff --git a/test/unit/util_spec.js b/test/unit/util_spec.js index 6ab0df3a1..bf9cedf93 100644 --- a/test/unit/util_spec.js +++ b/test/unit/util_spec.js @@ -1,5 +1,6 @@ /* globals expect, it, describe, combineUrl, Dict, isDict, Name, PDFJS, - stringToPDFString, isExternalLinkTargetSet, LinkTarget */ + stringToPDFString, isExternalLinkTargetSet, LinkTarget, + removeNullCharacters */ 'use strict'; @@ -125,4 +126,16 @@ describe('util', function() { // Reset the state. PDFJS.externalLinkTarget = previousExternalLinkTarget; }); + + describe('removeNullCharacters', function() { + it('should not modify string without null characters', function() { + var str = 'string without null chars'; + expect(removeNullCharacters(str)).toEqual('string without null chars'); + }); + + it('should modify string with null characters', function() { + var str = 'string\x00With\x00Null\x00Chars'; + expect(removeNullCharacters(str)).toEqual('stringWithNullChars'); + }); + }); }); diff --git a/web/pdf_attachment_view.js b/web/pdf_attachment_view.js index 1d39defe7..9ac37d441 100644 --- a/web/pdf_attachment_view.js +++ b/web/pdf_attachment_view.js @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals getFileName, removeNullCharacters */ +/* globals getFileName, PDFJS */ 'use strict'; @@ -89,7 +89,7 @@ var PDFAttachmentView = (function PDFAttachmentViewClosure() { div.className = 'attachmentsItem'; var button = document.createElement('button'); this._bindLink(button, item.content, filename); - button.textContent = removeNullCharacters(filename); + button.textContent = PDFJS.removeNullCharacters(filename); div.appendChild(button); this.container.appendChild(div); } diff --git a/web/pdf_outline_view.js b/web/pdf_outline_view.js index 84c83361c..c82131da7 100644 --- a/web/pdf_outline_view.js +++ b/web/pdf_outline_view.js @@ -12,7 +12,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -/* globals removeNullCharacters */ +/* globals PDFJS */ 'use strict'; @@ -137,7 +137,7 @@ var PDFOutlineView = (function PDFOutlineViewClosure() { div.className = 'outlineItem'; var element = document.createElement('a'); this._bindLink(element, item); - element.textContent = removeNullCharacters(item.title); + element.textContent = PDFJS.removeNullCharacters(item.title); div.appendChild(element); if (item.items.length > 0) { diff --git a/web/ui_utils.js b/web/ui_utils.js index 5f4b4fdc7..9b681ba9f 100644 --- a/web/ui_utils.js +++ b/web/ui_utils.js @@ -23,12 +23,6 @@ var MAX_AUTO_SCALE = 1.25; var SCROLLBAR_PADDING = 40; var VERTICAL_PADDING = 5; -var NullCharactersRegExp = /\x00/g; - -function removeNullCharacters(str) { - return str.replace(NullCharactersRegExp, ''); -} - function getFileName(url) { var anchor = url.indexOf('#'); var query = url.indexOf('?');