Merge pull request #20333 from calixteman/issue20302

Fix incremental saving with hybrid references
This commit is contained in:
calixteman 2025-10-04 20:31:09 +02:00 committed by GitHub
commit f56dc86014
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 29 additions and 26 deletions

View File

@ -566,7 +566,6 @@ class WorkerMessageHandler {
pdfManager.ensureCatalog("acroFormRef"), pdfManager.ensureCatalog("acroFormRef"),
pdfManager.ensureDoc("startXRef"), pdfManager.ensureDoc("startXRef"),
pdfManager.ensureDoc("xref"), pdfManager.ensureDoc("xref"),
pdfManager.ensureDoc("linearization"),
pdfManager.ensureCatalog("structTreeRoot"), pdfManager.ensureCatalog("structTreeRoot"),
]; ];
const changes = new RefSetCache(); const changes = new RefSetCache();
@ -581,7 +580,6 @@ class WorkerMessageHandler {
acroFormRef, acroFormRef,
startXRef, startXRef,
xref, xref,
linearization,
_structTreeRoot, _structTreeRoot,
] = await Promise.all(globalPromises); ] = await Promise.all(globalPromises);
const catalogRef = xref.trailer.getRaw("Root") || null; const catalogRef = xref.trailer.getRaw("Root") || null;
@ -736,9 +734,7 @@ class WorkerMessageHandler {
infoRef: xref.trailer.getRaw("Info") || null, infoRef: xref.trailer.getRaw("Info") || null,
infoMap, infoMap,
fileIds: xref.trailer.get("ID") || null, fileIds: xref.trailer.get("ID") || null,
startXRef: linearization startXRef,
? startXRef
: (xref.lastXRefStreamPos ?? startXRef),
filename, filename,
}; };
} }
@ -905,11 +901,6 @@ class WorkerMessageHandler {
handler.on("GetXFADatasets", function (data) { handler.on("GetXFADatasets", function (data) {
return pdfManager.ensureDoc("xfaDatasets"); return pdfManager.ensureDoc("xfaDatasets");
}); });
handler.on("GetXRefPrevValue", function (data) {
return pdfManager
.ensureXRef("trailer")
.then(trailer => trailer.get("Prev"));
});
handler.on("GetStartXRefPos", function (data) { handler.on("GetStartXRefPos", function (data) {
return pdfManager.ensureDoc("startXRef"); return pdfManager.ensureDoc("startXRef");
}); });

View File

@ -33,8 +33,6 @@ import { BaseStream } from "./base_stream.js";
import { CipherTransformFactory } from "./crypto.js"; import { CipherTransformFactory } from "./crypto.js";
class XRef { class XRef {
#firstXRefStmPos = null;
constructor(stream, pdfManager) { constructor(stream, pdfManager) {
this.stream = stream; this.stream = stream;
this.pdfManager = pdfManager; this.pdfManager = pdfManager;
@ -754,7 +752,6 @@ class XRef {
// (possible infinite recursion) // (possible infinite recursion)
this._xrefStms.add(obj); this._xrefStms.add(obj);
this.startXRefQueue.push(obj); this.startXRefQueue.push(obj);
this.#firstXRefStmPos ??= obj;
} }
} else if (Number.isInteger(obj)) { } else if (Number.isInteger(obj)) {
// Parse in-stream XRef // Parse in-stream XRef
@ -803,13 +800,6 @@ class XRef {
throw new XRefParseException(); throw new XRefParseException();
} }
get lastXRefStreamPos() {
return (
this.#firstXRefStmPos ??
(this._xrefStms.size > 0 ? Math.max(...this._xrefStms) : null)
);
}
getEntry(i) { getEntry(i) {
const xrefEntry = this.entries[i]; const xrefEntry = this.entries[i];
if (xrefEntry && !xrefEntry.free && xrefEntry.offset) { if (xrefEntry && !xrefEntry.free && xrefEntry.offset) {

View File

@ -752,9 +752,6 @@ class PDFDocumentProxy {
Object.defineProperty(this, "getXFADatasets", { Object.defineProperty(this, "getXFADatasets", {
value: () => this._transport.getXFADatasets(), value: () => this._transport.getXFADatasets(),
}); });
Object.defineProperty(this, "getXRefPrevValue", {
value: () => this._transport.getXRefPrevValue(),
});
Object.defineProperty(this, "getStartXRefPos", { Object.defineProperty(this, "getStartXRefPos", {
value: () => this._transport.getStartXRefPos(), value: () => this._transport.getStartXRefPos(),
}); });

View File

@ -0,0 +1 @@
https://github.com/user-attachments/files/22526382/JADC2.via.ABMS.PDF

View File

@ -13027,5 +13027,27 @@
"md5": "cc53e96a8fd9eafbfbb74de564f37047", "md5": "cc53e96a8fd9eafbfbb74de564f37047",
"rounds": 1, "rounds": 1,
"type": "eq" "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
}
}
} }
] ]

View File

@ -2499,6 +2499,8 @@ describe("api", function () {
let loadingTask = getDocument(buildGetDocumentParams("bug1823296.pdf")); let loadingTask = getDocument(buildGetDocumentParams("bug1823296.pdf"));
let pdfDoc = await loadingTask.promise; let pdfDoc = await loadingTask.promise;
let page = await pdfDoc.getPage(1);
const originalStructTree = await page.getStructTree();
pdfDoc.annotationStorage.setValue("pdfjs_internal_editor_0", { pdfDoc.annotationStorage.setValue("pdfjs_internal_editor_0", {
annotationType: AnnotationEditorType.FREETEXT, annotationType: AnnotationEditorType.FREETEXT,
rect: [12, 34, 56, 78], rect: [12, 34, 56, 78],
@ -2514,9 +2516,9 @@ describe("api", function () {
loadingTask = getDocument(data); loadingTask = getDocument(data);
pdfDoc = await loadingTask.promise; pdfDoc = await loadingTask.promise;
const xrefPrev = await pdfDoc.getXRefPrevValue(); page = await pdfDoc.getPage(1);
const newStructTree = await page.getStructTree();
expect(xrefPrev).toEqual(143954); expect(newStructTree).toEqual(originalStructTree);
await loadingTask.destroy(); await loadingTask.destroy();
}); });