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.
This commit is contained in:
Jonas Jenwald 2016-10-22 18:08:25 +02:00
parent d5e3b2fbf0
commit e1412de320

View File

@ -106,13 +106,21 @@ var PDFLinkService = (function PDFLinkServiceClosure() {
var goToDestination = function(destRef) { var goToDestination = function(destRef) {
// dest array looks like that: <page-ref> </XYZ|/FitXXX> <args..> // dest array looks like that: <page-ref> </XYZ|/FitXXX> <args..>
var pageNumber = destRef instanceof Object ? var pageNumber;
self._pagesRefCache[destRef.num + ' ' + destRef.gen + ' R'] : if (destRef instanceof Object) {
(destRef + 1); 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) {
if (pageNumber > self.pagesCount) { if (pageNumber < 1 || pageNumber > self.pagesCount) {
console.error('PDFLinkService_navigateTo: ' + console.error('PDFLinkService_navigateTo: "' + pageNumber +
'Trying to navigate to a non-existent page.'); '" is a non-existent page number.');
return; return;
} }
self.pdfViewer.scrollPageIntoView({ self.pdfViewer.scrollPageIntoView({
@ -130,10 +138,12 @@ var PDFLinkService = (function PDFLinkServiceClosure() {
} }
} else { } else {
self.pdfDocument.getPageIndex(destRef).then(function (pageIndex) { self.pdfDocument.getPageIndex(destRef).then(function (pageIndex) {
var pageNum = pageIndex + 1; self.cachePageRef(pageIndex + 1, destRef);
var cacheKey = destRef.num + ' ' + destRef.gen + ' R';
self._pagesRefCache[cacheKey] = pageNum;
goToDestination(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) { destinationPromise.then(function(destination) {
dest = destination; dest = destination;
if (!(destination instanceof Array)) { if (!(destination instanceof Array)) {
return; // invalid destination console.error('PDFLinkService_navigateTo: "' + destination +
'" is not a valid destination array.');
return;
} }
goToDestination(destination[0]); goToDestination(destination[0]);
}); });
@ -333,7 +345,12 @@ var PDFLinkService = (function PDFLinkServiceClosure() {
cachePageRef: function PDFLinkService_cachePageRef(pageNum, pageRef) { cachePageRef: function PDFLinkService_cachePageRef(pageNum, pageRef) {
var refStr = pageRef.num + ' ' + pageRef.gen + ' R'; var refStr = pageRef.num + ' ' + pageRef.gen + ' R';
this._pagesRefCache[refStr] = pageNum; 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) { function isValidExplicitDestination(dest) {