diff --git a/src/core/document.js b/src/core/document.js index c379a09ae..3cee33389 100644 --- a/src/core/document.js +++ b/src/core/document.js @@ -655,7 +655,7 @@ class PDFDocument { this.pdfManager = pdfManager; this.stream = stream; this.xref = new XRef(stream, pdfManager); - this._pagePromises = []; + this._pagePromises = new Map(); this._version = null; const idCounters = { @@ -1261,7 +1261,7 @@ class PDFDocument { ]); } - _getLinearizationPage(pageIndex) { + async _getLinearizationPage(pageIndex) { const { catalog, linearization } = this; if ( typeof PDFJSDev === "undefined" || @@ -1274,61 +1274,43 @@ class PDFDocument { } const ref = Ref.get(linearization.objectNumberFirst, 0); - return this.xref - .fetchAsync(ref) - .then(obj => { - // Ensure that the object that was found is actually a Page dictionary. - if ( - isDict(obj, "Page") || - (isDict(obj) && !obj.has("Type") && obj.has("Contents")) - ) { - if (ref && !catalog.pageKidsCountCache.has(ref)) { - catalog.pageKidsCountCache.put(ref, 1); // Cache the Page reference. - } - return [obj, ref]; + try { + const obj = await this.xref.fetchAsync(ref); + // Ensure that the object that was found is actually a Page dictionary. + if ( + isDict(obj, "Page") || + (isDict(obj) && !obj.has("Type") && obj.has("Contents")) + ) { + if (ref && !catalog.pageKidsCountCache.has(ref)) { + catalog.pageKidsCountCache.put(ref, 1); // Cache the Page reference. } - throw new FormatError( - "The Linearization dictionary doesn't point " + - "to a valid Page dictionary." - ); - }) - .catch(reason => { - info(reason); - return catalog.getPageDict(pageIndex); - }); + return [obj, ref]; + } + throw new FormatError( + "The Linearization dictionary doesn't point to a valid Page dictionary." + ); + } catch (reason) { + info(reason); + return catalog.getPageDict(pageIndex); + } } getPage(pageIndex) { - if (this._pagePromises[pageIndex] !== undefined) { - return this._pagePromises[pageIndex]; + const cachedPromise = this._pagePromises.get(pageIndex); + if (cachedPromise) { + return cachedPromise; } - const { catalog, linearization } = this; + const { catalog, linearization, xfaFactory } = this; - if (this.xfaFactory) { - return Promise.resolve( - new Page({ - pdfManager: this.pdfManager, - xref: this.xref, - pageIndex, - pageDict: Dict.empty, - ref: null, - globalIdFactory: this._globalIdFactory, - fontCache: catalog.fontCache, - builtInCMapCache: catalog.builtInCMapCache, - standardFontDataCache: catalog.standardFontDataCache, - globalImageCache: catalog.globalImageCache, - nonBlendModesSet: catalog.nonBlendModesSet, - xfaFactory: this.xfaFactory, - }) - ); + let promise; + if (xfaFactory) { + promise = Promise.resolve([Dict.empty, null]); + } else if (linearization && linearization.pageFirst === pageIndex) { + promise = this._getLinearizationPage(pageIndex); + } else { + promise = catalog.getPageDict(pageIndex); } - - const promise = - linearization && linearization.pageFirst === pageIndex - ? this._getLinearizationPage(pageIndex) - : catalog.getPageDict(pageIndex); - - return (this._pagePromises[pageIndex] = promise.then(([pageDict, ref]) => { + promise = promise.then(([pageDict, ref]) => { return new Page({ pdfManager: this.pdfManager, xref: this.xref, @@ -1341,9 +1323,12 @@ class PDFDocument { standardFontDataCache: catalog.standardFontDataCache, globalImageCache: catalog.globalImageCache, nonBlendModesSet: catalog.nonBlendModesSet, - xfaFactory: null, + xfaFactory, }); - })); + }); + + this._pagePromises.set(pageIndex, promise); + return promise; } checkFirstPage() { @@ -1352,7 +1337,7 @@ class PDFDocument { // Clear out the various caches to ensure that we haven't stored any // inconsistent and/or incorrect state, since that could easily break // subsequent `this.getPage` calls. - this._pagePromises.length = 0; + this._pagePromises.clear(); await this.cleanup(); throw new XRefParseException();