Don't iterate over all empty slots in the xref entries (bug 1980958)

This commit is contained in:
Calixte Denizet 2025-08-16 19:39:29 +02:00
parent 5d4f0659bc
commit af144be3ba
4 changed files with 33 additions and 3 deletions

View File

@ -681,11 +681,15 @@ class XRef {
// When no trailer dictionary candidate exists, try picking the first
// dictionary that contains a /Root entry (fixes issue18986.pdf).
if (!trailerDicts.length) {
for (const [num, entry] of this.entries.entries()) {
if (!entry) {
// In case, this.entries is a sparse array we don't want to
// iterate over empty entries so we use the `in` operator instead of
// using for..of on entries() or a for with the array length.
for (const num in this.entries) {
if (!Object.hasOwn(this.entries, num)) {
continue;
}
const ref = Ref.get(num, entry.gen);
const entry = this.entries[num];
const ref = Ref.get(parseInt(num), entry.gen);
let obj;
try {
@ -693,6 +697,7 @@ class XRef {
} catch {
continue;
}
if (obj instanceof BaseStream) {
obj = obj.dict;
}

View File

@ -741,3 +741,4 @@
!print_protection.pdf
!tracemonkey_with_annotations.pdf
!tracemonkey_with_editable_annotations.pdf
!bug1980958.pdf

10
test/pdfs/bug1980958.pdf Normal file
View File

@ -0,0 +1,10 @@
%PDF-1.7
1 0 obj <</Type /Catalog /Pages 2 0 R>>
endobj
2 0 obj <</Type /Pages /Kids [3 0 R] /Count 1>>
endobj
3 0 obj <</Type /Page /Parent 2 0 R /MediaBox [0 0 10 10]>>
endobj
2147483647 0 obj <</Root 1 0 R>>
endobj

View File

@ -878,6 +878,20 @@ describe("api", function () {
await loadingTask.destroy();
});
it("Doesn't iterate over all empty slots in the xref entries (bug 1980958)", async function () {
if (isNodeJS) {
pending("Worker is not supported in Node.js.");
}
const loadingTask = getDocument(buildGetDocumentParams("bug1980958.pdf"));
const { promise, resolve } = Promise.withResolvers();
setTimeout(() => resolve(null), 1000);
const pdfDocument = await Promise.race([loadingTask.promise, promise]);
expect(pdfDocument?.numPages).toEqual(1);
loadingTask._worker.destroy();
});
});
describe("PDFWorker", function () {