Add basic validation of the 'trailer' dictionary candidates in XRef.indexObjects (issue 9418)

This patch avoids choosing a (possible) 'trailer' dictionary that `XRef.parse` and/or the `Catalog` constructor/methods will reject anyway.
Since `XRef.indexObjects` is already parsing the entire PDF file, the extra dictionary look-ups added here shouldn't matter much. Besides, this is a fallback code-path that only applies to corrupt PDF files anyway.
This commit is contained in:
Jonas Jenwald 2018-06-19 11:31:31 +02:00
parent 346810e02a
commit 56e3648b65
4 changed files with 28 additions and 5 deletions

View File

@ -1260,7 +1260,7 @@ var XRef = (function XRefClosure() {
this.readXRef(/* recoveryMode */ true); this.readXRef(/* recoveryMode */ true);
} }
// finding main trailer // finding main trailer
var dict; let trailerDict;
for (i = 0, ii = trailers.length; i < ii; ++i) { for (i = 0, ii = trailers.length; i < ii; ++i) {
stream.pos = trailers[i]; stream.pos = trailers[i];
var parser = new Parser(new Lexer(stream), /* allowStreams = */ true, var parser = new Parser(new Lexer(stream), /* allowStreams = */ true,
@ -1270,18 +1270,33 @@ var XRef = (function XRefClosure() {
continue; continue;
} }
// read the trailer dictionary // read the trailer dictionary
dict = parser.getObj(); let dict = parser.getObj();
if (!isDict(dict)) { if (!isDict(dict)) {
continue; continue;
} }
// Do some basic validation of the trailer/root dictionary candidate.
let rootDict;
try {
rootDict = dict.get('Root');
} catch (ex) {
if (ex instanceof MissingDataException) {
throw ex;
}
continue;
}
if (!isDict(rootDict) || !rootDict.has('Pages')) {
continue;
}
// taking the first one with 'ID' // taking the first one with 'ID'
if (dict.has('ID')) { if (dict.has('ID')) {
return dict; return dict;
} }
// The current dictionary is a candidate, but continue searching.
trailerDict = dict;
} }
// no tailer with 'ID', taking last one (if exists) // No trailer with 'ID', taking last one (if exists).
if (dict) { if (trailerDict) {
return dict; return trailerDict;
} }
// nothing helps // nothing helps
throw new InvalidPDFException('Invalid PDF structure'); throw new InvalidPDFException('Invalid PDF structure');

View File

@ -68,6 +68,7 @@
!issue9252.pdf !issue9252.pdf
!issue9262_reduced.pdf !issue9262_reduced.pdf
!issue9291.pdf !issue9291.pdf
!issue9418.pdf
!issue9458.pdf !issue9458.pdf
!bad-PageLabels.pdf !bad-PageLabels.pdf
!decodeACSuccessive.pdf !decodeACSuccessive.pdf

BIN
test/pdfs/issue9418.pdf Normal file

Binary file not shown.

View File

@ -748,6 +748,13 @@
"link": false, "link": false,
"type": "eq" "type": "eq"
}, },
{ "id": "issue9418",
"file": "pdfs/issue9418.pdf",
"md5": "32ecad8098acb1938539d47944ecb54b",
"rounds": 1,
"link": false,
"type": "eq"
},
{ "id": "issue9262", { "id": "issue9262",
"file": "pdfs/issue9262_reduced.pdf", "file": "pdfs/issue9262_reduced.pdf",
"md5": "5347ce2d7b3866625c22e115fd90e0de", "md5": "5347ce2d7b3866625c22e115fd90e0de",