From d5e3b2fbf0eb21d6acfd79a7bce91436d0e2220f Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 22 Oct 2016 17:44:17 +0200 Subject: [PATCH 1/2] Update `PDFOutlineViewer_bindLink` to look more like `LinkAnnotationElement_bindLink` --- src/display/annotation_layer.js | 2 +- web/pdf_outline_viewer.js | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/display/annotation_layer.js b/src/display/annotation_layer.js index 88c0c369e..a26382673 100644 --- a/src/display/annotation_layer.js +++ b/src/display/annotation_layer.js @@ -299,7 +299,7 @@ var LinkAnnotationElement = (function LinkAnnotationElementClosure() { if (this.data.action) { this._bindNamedAction(link, this.data.action); } else { - this._bindLink(link, (this.data.dest || null)); + this._bindLink(link, this.data.dest); } } diff --git a/web/pdf_outline_viewer.js b/web/pdf_outline_viewer.js index 028e7a5ea..84f9c28c1 100644 --- a/web/pdf_outline_viewer.js +++ b/web/pdf_outline_viewer.js @@ -90,10 +90,13 @@ var PDFOutlineViewer = (function PDFOutlineViewerClosure() { }); return; } - var linkService = this.linkService; - element.href = linkService.getDestinationHash(item.dest); - element.onclick = function goToDestination(e) { - linkService.navigateTo(item.dest); + var self = this, destination = item.dest; + + element.href = self.linkService.getDestinationHash(destination); + element.onclick = function () { + if (destination) { + self.linkService.navigateTo(destination); + } return false; }; }, From e1412de32075e76f3c6129dc59ef6631cc68b6c6 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 22 Oct 2016 18:08:25 +0200 Subject: [PATCH 2/2] Add more validation to `PDFLinkService_navigateTo` In some PDF files, the first element (i.e. the one containing either a `Ref` or a `Number` pointing to a page) of the explicit destination Array may be bogus. One such example is actually the file `pdf.pdf` in the test-suite, where some destinations are incompletely specified. One such example being the `G1.998360` destination whose explicit destination Array contains `[null, /XYZ, 54, 488, null]`, i.e. the destination page is `null`. Hence this patch adds a bit more validation for that case. It also adds an additional check to ensure that the resulting `pageNumber` is non-negative, and finally a couple more error messages for existing cases of malformed data. --- web/pdf_link_service.js | 39 ++++++++++++++++++++++++++++----------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/web/pdf_link_service.js b/web/pdf_link_service.js index 045913a56..28945180e 100644 --- a/web/pdf_link_service.js +++ b/web/pdf_link_service.js @@ -106,13 +106,21 @@ var PDFLinkService = (function PDFLinkServiceClosure() { var goToDestination = function(destRef) { // dest array looks like that: - var pageNumber = destRef instanceof Object ? - self._pagesRefCache[destRef.num + ' ' + destRef.gen + ' R'] : - (destRef + 1); + var pageNumber; + if (destRef instanceof Object) { + pageNumber = self._cachedPageNumber(destRef); + } else if ((destRef | 0) === destRef) { // Integer + pageNumber = destRef + 1; + } else { + console.error('PDFLinkService_navigateTo: "' + destRef + + '" is not a valid destination reference.'); + return; + } + if (pageNumber) { - if (pageNumber > self.pagesCount) { - console.error('PDFLinkService_navigateTo: ' + - 'Trying to navigate to a non-existent page.'); + if (pageNumber < 1 || pageNumber > self.pagesCount) { + console.error('PDFLinkService_navigateTo: "' + pageNumber + + '" is a non-existent page number.'); return; } self.pdfViewer.scrollPageIntoView({ @@ -130,10 +138,12 @@ var PDFLinkService = (function PDFLinkServiceClosure() { } } else { self.pdfDocument.getPageIndex(destRef).then(function (pageIndex) { - var pageNum = pageIndex + 1; - var cacheKey = destRef.num + ' ' + destRef.gen + ' R'; - self._pagesRefCache[cacheKey] = pageNum; + self.cachePageRef(pageIndex + 1, destRef); goToDestination(destRef); + }).catch(function () { + console.error('PDFLinkService_navigateTo: "' + destRef + + '" is not a valid page reference.'); + return; }); } }; @@ -148,7 +158,9 @@ var PDFLinkService = (function PDFLinkServiceClosure() { destinationPromise.then(function(destination) { dest = destination; if (!(destination instanceof Array)) { - return; // invalid destination + console.error('PDFLinkService_navigateTo: "' + destination + + '" is not a valid destination array.'); + return; } goToDestination(destination[0]); }); @@ -333,7 +345,12 @@ var PDFLinkService = (function PDFLinkServiceClosure() { cachePageRef: function PDFLinkService_cachePageRef(pageNum, pageRef) { var refStr = pageRef.num + ' ' + pageRef.gen + ' R'; this._pagesRefCache[refStr] = pageNum; - } + }, + + _cachedPageNumber: function PDFLinkService_cachedPageNumber(pageRef) { + var refStr = pageRef.num + ' ' + pageRef.gen + ' R'; + return (this._pagesRefCache && this._pagesRefCache[refStr]) || null; + }, }; function isValidExplicitDestination(dest) {