Merge pull request #14411 from Snuffleupagus/getAllPageDicts-async

Convert `Catalog.getAllPageDicts` to an `async` method
This commit is contained in:
Tim van der Meij 2022-01-01 14:43:20 +01:00 committed by GitHub
commit f287c5f817
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 39 deletions

View File

@ -1210,9 +1210,9 @@ class Catalog {
/** /**
* Eagerly fetches the entire /Pages-tree; should ONLY be used as a fallback. * Eagerly fetches the entire /Pages-tree; should ONLY be used as a fallback.
* @returns {Map} * @returns {Promise<Map>}
*/ */
getAllPageDicts(recoveryMode = false) { async getAllPageDicts(recoveryMode = false) {
const queue = [{ currentNode: this.toplevelPagesDict, posInKids: 0 }]; const queue = [{ currentNode: this.toplevelPagesDict, posInKids: 0 }];
const visitedNodes = new RefSet(); const visitedNodes = new RefSet();
@ -1221,6 +1221,7 @@ class Catalog {
visitedNodes.put(pagesRef); visitedNodes.put(pagesRef);
} }
const map = new Map(), const map = new Map(),
xref = this.xref,
pageIndexCache = this.pageIndexCache; pageIndexCache = this.pageIndexCache;
let pageIndex = 0; let pageIndex = 0;
@ -1233,6 +1234,10 @@ class Catalog {
map.set(pageIndex++, [pageDict, pageRef]); map.set(pageIndex++, [pageDict, pageRef]);
} }
function addPageError(error) { function addPageError(error) {
if (error instanceof XRefEntryException && !recoveryMode) {
throw error;
}
map.set(pageIndex++, [error, null]); map.set(pageIndex++, [error, null]);
} }
@ -1240,18 +1245,14 @@ class Catalog {
const queueItem = queue[queue.length - 1]; const queueItem = queue[queue.length - 1];
const { currentNode, posInKids } = queueItem; const { currentNode, posInKids } = queueItem;
let kids; let kids = currentNode.getRaw("Kids");
try { if (kids instanceof Ref) {
kids = currentNode.get("Kids"); try {
} catch (ex) { kids = await xref.fetchAsync(kids);
if (ex instanceof MissingDataException) { } catch (ex) {
throw ex; addPageError(ex);
break;
} }
if (ex instanceof XRefEntryException && !recoveryMode) {
throw ex;
}
addPageError(ex);
break;
} }
if (!Array.isArray(kids)) { if (!Array.isArray(kids)) {
addPageError( addPageError(
@ -1268,18 +1269,6 @@ class Catalog {
const kidObj = kids[posInKids]; const kidObj = kids[posInKids];
let obj; let obj;
if (kidObj instanceof Ref) { if (kidObj instanceof Ref) {
try {
obj = this.xref.fetch(kidObj);
} catch (ex) {
if (ex instanceof MissingDataException) {
throw ex;
}
if (ex instanceof XRefEntryException && !recoveryMode) {
throw ex;
}
addPageError(ex);
break;
}
// Prevent circular references in the /Pages tree. // Prevent circular references in the /Pages tree.
if (visitedNodes.has(kidObj)) { if (visitedNodes.has(kidObj)) {
addPageError( addPageError(
@ -1288,6 +1277,13 @@ class Catalog {
break; break;
} }
visitedNodes.put(kidObj); visitedNodes.put(kidObj);
try {
obj = await xref.fetchAsync(kidObj);
} catch (ex) {
addPageError(ex);
break;
}
} else { } else {
// Prevent errors in corrupt PDF documents that violate the // Prevent errors in corrupt PDF documents that violate the
// specification by *inlining* Page dicts directly in the Kids // specification by *inlining* Page dicts directly in the Kids
@ -1303,18 +1299,14 @@ class Catalog {
break; break;
} }
let type; let type = obj.getRaw("Type");
try { if (type instanceof Ref) {
type = obj.get("Type"); try {
} catch (ex) { type = await xref.fetchAsync(type);
if (ex instanceof MissingDataException) { } catch (ex) {
throw ex; addPageError(ex);
break;
} }
if (ex instanceof XRefEntryException && !recoveryMode) {
throw ex;
}
addPageError(ex);
break;
} }
if (isName(type, "Page") || !obj.has("Kids")) { if (isName(type, "Page") || !obj.has("Kids")) {
addPageDict(obj, kidObj instanceof Ref ? kidObj : null); addPageDict(obj, kidObj instanceof Ref ? kidObj : null);

View File

@ -1401,9 +1401,7 @@ class PDFDocument {
let pagesTree; let pagesTree;
try { try {
pagesTree = await pdfManager.ensureCatalog("getAllPageDicts", [ pagesTree = await catalog.getAllPageDicts(recoveryMode);
recoveryMode,
]);
} catch (reasonAll) { } catch (reasonAll) {
if (reasonAll instanceof XRefEntryException && !recoveryMode) { if (reasonAll instanceof XRefEntryException && !recoveryMode) {
throw new XRefParseException(); throw new XRefParseException();