From 19ff14816389b3716b80f5ffbcb5173c1497eb5c Mon Sep 17 00:00:00 2001 From: Calixte Denizet Date: Fri, 3 Oct 2025 20:12:22 +0200 Subject: [PATCH] Fix incremental saving with hybrid references This patch removes some previous fixes which are now likely fixed by #17636. Fixes #20302. --- src/core/worker.js | 11 +---------- src/core/xref.js | 10 ---------- src/display/api.js | 3 --- test/pdfs/issue20302.pdf.link | 1 + test/test_manifest.json | 22 ++++++++++++++++++++++ test/unit/api_spec.js | 8 +++++--- 6 files changed, 29 insertions(+), 26 deletions(-) create mode 100644 test/pdfs/issue20302.pdf.link diff --git a/src/core/worker.js b/src/core/worker.js index b94fb7068..578ea2bdb 100644 --- a/src/core/worker.js +++ b/src/core/worker.js @@ -566,7 +566,6 @@ class WorkerMessageHandler { pdfManager.ensureCatalog("acroFormRef"), pdfManager.ensureDoc("startXRef"), pdfManager.ensureDoc("xref"), - pdfManager.ensureDoc("linearization"), pdfManager.ensureCatalog("structTreeRoot"), ]; const changes = new RefSetCache(); @@ -581,7 +580,6 @@ class WorkerMessageHandler { acroFormRef, startXRef, xref, - linearization, _structTreeRoot, ] = await Promise.all(globalPromises); const catalogRef = xref.trailer.getRaw("Root") || null; @@ -736,9 +734,7 @@ class WorkerMessageHandler { infoRef: xref.trailer.getRaw("Info") || null, infoMap, fileIds: xref.trailer.get("ID") || null, - startXRef: linearization - ? startXRef - : (xref.lastXRefStreamPos ?? startXRef), + startXRef, filename, }; } @@ -905,11 +901,6 @@ class WorkerMessageHandler { handler.on("GetXFADatasets", function (data) { return pdfManager.ensureDoc("xfaDatasets"); }); - handler.on("GetXRefPrevValue", function (data) { - return pdfManager - .ensureXRef("trailer") - .then(trailer => trailer.get("Prev")); - }); handler.on("GetStartXRefPos", function (data) { return pdfManager.ensureDoc("startXRef"); }); diff --git a/src/core/xref.js b/src/core/xref.js index 8ffbefcc1..c13c08a7d 100644 --- a/src/core/xref.js +++ b/src/core/xref.js @@ -33,8 +33,6 @@ import { BaseStream } from "./base_stream.js"; import { CipherTransformFactory } from "./crypto.js"; class XRef { - #firstXRefStmPos = null; - constructor(stream, pdfManager) { this.stream = stream; this.pdfManager = pdfManager; @@ -754,7 +752,6 @@ class XRef { // (possible infinite recursion) this._xrefStms.add(obj); this.startXRefQueue.push(obj); - this.#firstXRefStmPos ??= obj; } } else if (Number.isInteger(obj)) { // Parse in-stream XRef @@ -803,13 +800,6 @@ class XRef { throw new XRefParseException(); } - get lastXRefStreamPos() { - return ( - this.#firstXRefStmPos ?? - (this._xrefStms.size > 0 ? Math.max(...this._xrefStms) : null) - ); - } - getEntry(i) { const xrefEntry = this.entries[i]; if (xrefEntry && !xrefEntry.free && xrefEntry.offset) { diff --git a/src/display/api.js b/src/display/api.js index 9283adecb..336472b47 100644 --- a/src/display/api.js +++ b/src/display/api.js @@ -752,9 +752,6 @@ class PDFDocumentProxy { Object.defineProperty(this, "getXFADatasets", { value: () => this._transport.getXFADatasets(), }); - Object.defineProperty(this, "getXRefPrevValue", { - value: () => this._transport.getXRefPrevValue(), - }); Object.defineProperty(this, "getStartXRefPos", { value: () => this._transport.getStartXRefPos(), }); diff --git a/test/pdfs/issue20302.pdf.link b/test/pdfs/issue20302.pdf.link new file mode 100644 index 000000000..e2de78703 --- /dev/null +++ b/test/pdfs/issue20302.pdf.link @@ -0,0 +1 @@ +https://github.com/user-attachments/files/22526382/JADC2.via.ABMS.PDF diff --git a/test/test_manifest.json b/test/test_manifest.json index 6a810a98c..03d1f1d71 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -13027,5 +13027,27 @@ "md5": "cc53e96a8fd9eafbfbb74de564f37047", "rounds": 1, "type": "eq" + }, + { + "id": "issue20302-save-print", + "file": "pdfs/issue20302.pdf", + "md5": "d8db2fa1889fd14effcfa5b597b6fe7b", + "rounds": 1, + "lastPage": 1, + "type": "eq", + "link": true, + "save": true, + "print": true, + "annotationStorage": { + "pdfjs_internal_editor_0": { + "annotationType": 3, + "color": [0, 0, 0], + "fontSize": 10, + "value": "Hello World", + "pageIndex": 0, + "rect": [115, 325, 171, 342], + "rotation": 0 + } + } } ] diff --git a/test/unit/api_spec.js b/test/unit/api_spec.js index a006bb226..a8e0fbc07 100644 --- a/test/unit/api_spec.js +++ b/test/unit/api_spec.js @@ -2499,6 +2499,8 @@ describe("api", function () { let loadingTask = getDocument(buildGetDocumentParams("bug1823296.pdf")); let pdfDoc = await loadingTask.promise; + let page = await pdfDoc.getPage(1); + const originalStructTree = await page.getStructTree(); pdfDoc.annotationStorage.setValue("pdfjs_internal_editor_0", { annotationType: AnnotationEditorType.FREETEXT, rect: [12, 34, 56, 78], @@ -2514,9 +2516,9 @@ describe("api", function () { loadingTask = getDocument(data); pdfDoc = await loadingTask.promise; - const xrefPrev = await pdfDoc.getXRefPrevValue(); - - expect(xrefPrev).toEqual(143954); + page = await pdfDoc.getPage(1); + const newStructTree = await page.getStructTree(); + expect(newStructTree).toEqual(originalStructTree); await loadingTask.destroy(); });