From b26dc1939207ac16acc3a2ffbb768ee37becdd0c Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Fri, 1 Nov 2024 17:22:46 +0100 Subject: [PATCH] Ensure that serializing of StructTree-data cannot fail during loading I discovered that doing skip-cache re-reloading of https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/PDF32000_2008.pdf would *intermittently* cause (some of) the AnnotationLayers to break with errors printed in the console (see below). In hindsight this bug is really obvious, however it took me quite some time to find it, since the `StructTreePage.prototype.serializable` getter will lookup various data and all of those cases can fail during loading when streaming and/or range requests are being used. Finally, to prevent any future errors, ensure that the viewer won't break in these sort of situations. ``` Uncaught (in promise) Object { message: "Missing data [19098296, 19098297)", name: "UnknownErrorException", details: "MissingDataException: Missing data [19098296, 19098297)", stack: "BaseExceptionClosure@resource://pdf.js/build/pdf.mjs:453:29\n@resource://pdf.js/build/pdf.mjs:456:2\n" } viewer.mjs:8801:55 \#renderAnnotationLayer: "UnknownErrorException: Missing data [17552729, 17552730)". viewer.mjs:8737:15 Uncaught (in promise) Object { message: "Missing data [17552729, 17552730)", name: "UnknownErrorException", details: "MissingDataException: Missing data [17552729, 17552730)", stack: "BaseExceptionClosure@resource://pdf.js/build/pdf.mjs:453:29\n@resource://pdf.js/build/pdf.mjs:456:2\n" } viewer.mjs:8801:55 ``` --- src/core/document.js | 2 +- web/struct_tree_layer_builder.js | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/core/document.js b/src/core/document.js index 434cbac2a6325..25952d0016979 100644 --- a/src/core/document.js +++ b/src/core/document.js @@ -707,7 +707,7 @@ class Page { const structTree = await this.pdfManager.ensure(this, "_parseStructTree", [ structTreeRoot, ]); - return structTree.serializable; + return this.pdfManager.ensure(structTree, "serializable"); } /** diff --git a/web/struct_tree_layer_builder.js b/web/struct_tree_layer_builder.js index ead85bbf12507..72ba6bc5c111c 100644 --- a/web/struct_tree_layer_builder.js +++ b/web/struct_tree_layer_builder.js @@ -112,8 +112,14 @@ class StructTreeLayerBuilder { } async getAriaAttributes(annotationId) { - await this.render(); - return this.#elementAttributes.get(annotationId); + try { + await this.render(); + return this.#elementAttributes.get(annotationId); + } catch { + // If the structTree cannot be fetched, parsed, and/or rendered, + // ensure that e.g. the AnnotationLayer won't break completely. + } + return null; } hide() {