Skip to content

Commit

Permalink
Fallback and try a *previous* generation if all else fails in `XRef.i…
Browse files Browse the repository at this point in the history
…ndexObjects` (issue 15577)

When we fail to find a usable PDF document `trailer` *and* there were errors during parsing, try and fallback to a *previous* generation as a last resort during fetching of uncompressed references.
*Please note:* This will not affect "normal" PDF documents, with valid /XRef data, and even most *corrupt* documents should be completely unaffected by these changes.
  • Loading branch information
Snuffleupagus committed Oct 18, 2022
1 parent 9355b72 commit de99f99
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 3 deletions.
24 changes: 21 additions & 3 deletions src/core/xref.js
Original file line number Diff line number Diff line change
Expand Up @@ -556,8 +556,15 @@ class XRef {
this.readXRef(/* recoveryMode */ true);
}
// finding main trailer
let trailerDict;
for (const trailer of trailers) {
let trailerDict, trailerError;
for (const trailer of [...trailers, "generationFallback", ...trailers]) {
if (trailer === "generationFallback") {
if (!trailerError) {
break; // No need to fallback if there were no validation errors.
}
this._generationFallback = true;
continue;
}
stream.pos = trailer;
const parser = new Parser({
lexer: new Lexer(stream),
Expand Down Expand Up @@ -590,6 +597,7 @@ class XRef {
}
// The top-level /Pages dictionary isn't obviously corrupt.
} catch (ex) {
trailerError = ex;
continue;
}
// taking the first one with 'ID'
Expand Down Expand Up @@ -780,7 +788,17 @@ class XRef {
const gen = ref.gen;
let num = ref.num;
if (xrefEntry.gen !== gen) {
throw new XRefEntryException(`Inconsistent generation in XRef: ${ref}`);
const msg = `Inconsistent generation in XRef: ${ref}`;
// Try falling back to a *previous* generation (fixes issue15577.pdf).
if (this._generationFallback && xrefEntry.gen < gen) {
warn(msg);
return this.fetchUncompressed(
Ref.get(num, xrefEntry.gen),
xrefEntry,
suppressEncryption
);
}
throw new XRefEntryException(msg);
}
const stream = this.stream.makeSubStream(
xrefEntry.offset + this.stream.start
Expand Down
1 change: 1 addition & 0 deletions test/pdfs/issue15577.pdf.link
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
https://github.com/mozilla/pdf.js/files/9813960/hang-080214-152005-90.pdf
8 changes: 8 additions & 0 deletions test/test_manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -661,6 +661,14 @@
"lastPage": 1,
"type": "eq"
},
{ "id": "issue15577",
"file": "pdfs/issue15577.pdf",
"md5": "6939244cf44b7b31ff960b58ed7e4004",
"link": true,
"rounds": 1,
"lastPage": 1,
"type": "eq"
},
{ "id": "hmm-pdf",
"file": "pdfs/hmm.pdf",
"md5": "e08467e60101ee5f4a59716e86db6dc9",
Expand Down

0 comments on commit de99f99

Please sign in to comment.