Fallback and try a *previous* generation if all else fails in XRef.indexObjects
(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.
This commit is contained in:
parent
9355b72931
commit
de99f99a01
@ -556,8 +556,15 @@ class XRef {
|
|||||||
this.readXRef(/* recoveryMode */ true);
|
this.readXRef(/* recoveryMode */ true);
|
||||||
}
|
}
|
||||||
// finding main trailer
|
// finding main trailer
|
||||||
let trailerDict;
|
let trailerDict, trailerError;
|
||||||
for (const trailer of trailers) {
|
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;
|
stream.pos = trailer;
|
||||||
const parser = new Parser({
|
const parser = new Parser({
|
||||||
lexer: new Lexer(stream),
|
lexer: new Lexer(stream),
|
||||||
@ -590,6 +597,7 @@ class XRef {
|
|||||||
}
|
}
|
||||||
// The top-level /Pages dictionary isn't obviously corrupt.
|
// The top-level /Pages dictionary isn't obviously corrupt.
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
|
trailerError = ex;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// taking the first one with 'ID'
|
// taking the first one with 'ID'
|
||||||
@ -780,7 +788,17 @@ class XRef {
|
|||||||
const gen = ref.gen;
|
const gen = ref.gen;
|
||||||
let num = ref.num;
|
let num = ref.num;
|
||||||
if (xrefEntry.gen !== gen) {
|
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(
|
const stream = this.stream.makeSubStream(
|
||||||
xrefEntry.offset + this.stream.start
|
xrefEntry.offset + this.stream.start
|
||||||
|
1
test/pdfs/issue15577.pdf.link
Normal file
1
test/pdfs/issue15577.pdf.link
Normal file
@ -0,0 +1 @@
|
|||||||
|
https://github.com/mozilla/pdf.js/files/9813960/hang-080214-152005-90.pdf
|
@ -661,6 +661,14 @@
|
|||||||
"lastPage": 1,
|
"lastPage": 1,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "issue15577",
|
||||||
|
"file": "pdfs/issue15577.pdf",
|
||||||
|
"md5": "6939244cf44b7b31ff960b58ed7e4004",
|
||||||
|
"link": true,
|
||||||
|
"rounds": 1,
|
||||||
|
"lastPage": 1,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "hmm-pdf",
|
{ "id": "hmm-pdf",
|
||||||
"file": "pdfs/hmm.pdf",
|
"file": "pdfs/hmm.pdf",
|
||||||
"md5": "e08467e60101ee5f4a59716e86db6dc9",
|
"md5": "e08467e60101ee5f4a59716e86db6dc9",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user