From 64679073185be2b1983ddd8834a29f353bdb0de4 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 22 Jun 2021 15:44:52 +0200 Subject: [PATCH] Support corrupt documents with *empty* `Name`-entries (issue 13610) Apparently some really bad PDF software can create documents with *empty* `Name`-entries, which we thus need to somehow deal with. While I don't know if this patch is necessarily the best solution, it should at least ensure that the *empty* `Name`-instance cannot accidentally match a proper `Name`-instance (and it doesn't require changes to a lot of existing code).[1] --- [1] I briefly considered using a `Symbol` rather than an Object, but quickly decided against that since the former one [is not clonable](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm#supported_types) and `Name`-instances may be sent to the API. --- src/core/parser.js | 3 +++ src/core/primitives.js | 6 ++++++ test/pdfs/issue13610.pdf.link | 1 + test/test_manifest.json | 7 +++++++ test/unit/evaluator_spec.js | 2 +- 5 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 test/pdfs/issue13610.pdf.link diff --git a/src/core/parser.js b/src/core/parser.js index b3970f7bf..bc8381070 100644 --- a/src/core/parser.js +++ b/src/core/parser.js @@ -1113,6 +1113,9 @@ class Lexer { } if (strBuf.length > 127) { warn(`Name token is longer than allowed by the spec: ${strBuf.length}`); + } else if (strBuf.length === 0) { + warn("Name token is empty."); + return Name.empty; } return Name.get(strBuf.join("")); } diff --git a/src/core/primitives.js b/src/core/primitives.js index c35dedef5..4e96b7b85 100644 --- a/src/core/primitives.js +++ b/src/core/primitives.js @@ -33,6 +33,12 @@ const Name = (function NameClosure() { return nameValue ? nameValue : (nameCache[name] = new Name(name)); } + static get empty() { + // eslint-disable-next-line no-restricted-syntax + const emptyName = new Name({ empty: true }); + return shadow(this, "empty", emptyName); + } + static _clearCache() { nameCache = Object.create(null); } diff --git a/test/pdfs/issue13610.pdf.link b/test/pdfs/issue13610.pdf.link new file mode 100644 index 000000000..1ca4adb7b --- /dev/null +++ b/test/pdfs/issue13610.pdf.link @@ -0,0 +1 @@ +https://github.com/mozilla/pdf.js/files/6694277/Unitfactuur_18707277_KORTELAND_PRINTEN.INSCANNEN.pdf diff --git a/test/test_manifest.json b/test/test_manifest.json index f203d4b8a..b8e9c94b0 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -1612,6 +1612,13 @@ "rounds": 1, "type": "eq" }, + { "id": "issue13610", + "file": "pdfs/issue13610.pdf", + "md5": "5b894c0b1b2279a245c23abd76648ca9", + "link": true, + "rounds": 1, + "type": "eq" + }, { "id": "simpletype3font-text", "file": "pdfs/simpletype3font.pdf", "md5": "b374c7543920840c61999e9e86939f99", diff --git a/test/unit/evaluator_spec.js b/test/unit/evaluator_spec.js index 4379095dd..0b651e3a8 100644 --- a/test/unit/evaluator_spec.js +++ b/test/unit/evaluator_spec.js @@ -325,7 +325,7 @@ describe("evaluator", function () { expect(false).toEqual(true); } catch (reason) { expect(reason instanceof FormatError).toEqual(true); - expect(reason.message).toEqual("XObject must be referred to by name."); + expect(reason.message).toEqual("XObject should be a stream"); } });