From fdad0a0b0b7a4c870428372f6c21970c20f3e3a9 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 20 Nov 2018 12:34:25 +0100 Subject: [PATCH] Fallback to an exhaustive search, in corrupt PDF files, for NameTrees/NumberTrees that are not correctly ordered (issue 10272) According to the specification, see https://www.adobe.com/content/dam/acom/en/devnet/acrobat/pdfs/PDF32000_2008.pdf#G6.2384179, the keys of NameTree/NumberTree should be ordered. For corrupt PDF files, which violate this assumption, we thus need to fallback to an exhaustive search in order to e.g. find all destinations. *Please note:* Given that this only implements a fallback for the "final" node of the Tree, there's obviously a risk that the patch isn't sufficient for dealing with all kinds of out-of-order corruption. However, this kind of problem should be rare in practice, and without a real-world test-case it's difficult to implement a completely general solution (and there's obviously a question if you'd even want to). --- src/core/obj.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/core/obj.js b/src/core/obj.js index f05d373a2..019fe5bf6 100644 --- a/src/core/obj.js +++ b/src/core/obj.js @@ -1648,7 +1648,7 @@ class NameOrNumberTree { // contains the key we are looking for. while (kidsOrEntries.has('Kids')) { if (++loopCount > MAX_LEVELS) { - warn('Search depth limit reached for "' + this._type + '" tree.'); + warn(`Search depth limit reached for "${this._type}" tree.`); return null; } @@ -1696,6 +1696,19 @@ class NameOrNumberTree { return xref.fetchIfRef(entries[m + 1]); } } + + // Fallback to an exhaustive search, in an attempt to handle corrupt + // PDF files where keys are not correctly ordered (fixes issue 10272). + info(`Falling back to an exhaustive search, for key "${key}", ` + + `in "${this._type}" tree.`); + for (let m = 0, mm = entries.length; m < mm; m += 2) { + const currentKey = xref.fetchIfRef(entries[m]); + if (currentKey === key) { + warn(`The "${key}" key was found at an incorrect, ` + + `i.e. out-of-order, position in "${this._type}" tree.`); + return xref.fetchIfRef(entries[m + 1]); + } + } } return null; }