diff --git a/src/core/xref.js b/src/core/xref.js index c55715463..b378e9476 100644 --- a/src/core/xref.js +++ b/src/core/xref.js @@ -581,16 +581,11 @@ class XRef { this.startXRefQueue.push(xrefStm); this.readXRef(/* recoveryMode */ true); } - // finding main trailer - 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; - } + + const trailerDicts = []; + // Pre-parsing the trailers to check if the document is possibly encrypted. + let isEncrypted = false; + for (const trailer of trailers) { stream.pos = trailer; const parser = new Parser({ lexer: new Lexer(stream), @@ -607,6 +602,23 @@ class XRef { if (!(dict instanceof Dict)) { continue; } + trailerDicts.push(dict); + + if (dict.has("Encrypt")) { + isEncrypted = true; + } + } + + // finding main trailer + let trailerDict, trailerError; + for (const dict of [...trailerDicts, "genFallback", ...trailerDicts]) { + if (dict === "genFallback") { + if (!trailerError) { + break; // No need to fallback if there were no validation errors. + } + this._generationFallback = true; + continue; + } // Do some basic validation of the trailer/root dictionary candidate. let validPagesDict = false; try { @@ -628,7 +640,11 @@ class XRef { continue; } // taking the first one with 'ID' - if (validPagesDict && dict.has("ID")) { + if ( + validPagesDict && + (!isEncrypted || dict.has("Encrypt")) && + dict.has("ID") + ) { return dict; } // The current dictionary is a candidate, but continue searching. diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index 4439ffd3d..bb699a606 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -413,6 +413,7 @@ !issue2128r.pdf !bug1703683_page2_reduced.pdf !issue5540.pdf +!issue15893_reduced.pdf !issue5549.pdf !visibility_expressions.pdf !issue5475.pdf diff --git a/test/pdfs/issue15893_reduced.pdf b/test/pdfs/issue15893_reduced.pdf new file mode 100644 index 000000000..1a4e66fbe Binary files /dev/null and b/test/pdfs/issue15893_reduced.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index 70f277edd..d126594d3 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -386,6 +386,13 @@ "lastPage": 4, "type": "eq" }, + { "id": "issue15893_reduced", + "file": "pdfs/issue15893_reduced.pdf", + "md5": "cf889b927f9f53d164622a99378bf39d", + "rounds": 1, + "type": "eq", + "password": "test" + }, { "id": "bug1727053", "file": "pdfs/bug1727053.pdf", "md5": "8ed1e52da64000f9fdcb8b732f5a58f8",