diff --git a/src/core/xref.js b/src/core/xref.js index 9159ad437..dcbd49307 100644 --- a/src/core/xref.js +++ b/src/core/xref.js @@ -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), @@ -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' @@ -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 diff --git a/test/pdfs/issue15577.pdf.link b/test/pdfs/issue15577.pdf.link new file mode 100644 index 000000000..368a1d77e --- /dev/null +++ b/test/pdfs/issue15577.pdf.link @@ -0,0 +1 @@ +https://github.com/mozilla/pdf.js/files/9813960/hang-080214-152005-90.pdf diff --git a/test/test_manifest.json b/test/test_manifest.json index 55b5a0e6f..aa7368805 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -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",