From 2e9cd3ea64997ff43904082f1ec07244abf38e46 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Mon, 23 May 2016 15:32:04 +0200 Subject: [PATCH 1/3] Slightly refactor the `fontRef` handling in `PartialEvaluator_loadFont` (issue 7403 and issue 7402) Originally, I was just going to change this code to use `Ref_toString` in a couple more places. When I started reading the code, I figured that it wouldn't hurt to clean up a couple of comments. While doing this, I noticed that the logic for the (rare) `isDict(fontRef)` case could do with a few improvements. There should be no functional changes with this patch, but given the added reference checks, we will now avoid bogus `Ref`s when resolving font aliases. In practice, as issue 7403 shows, the current code can break certain PDF files even if it's very rare. Note that the only thing that this patch will change, is the `font.loadedName` in the case where a `fontRef` is a reference *and* the font doesn't have a descriptor. Previously for `fontRef = Ref(4, 0)` we'd get `font.loadedName = 'g_d0_f4_0'`, and with this patch `font.loadedName = g_d0_f4R`, which is actually one character shorted in most cases. (Given that `Ref_toString` contains an optimization for the `gen === 0` case, which is by far the most common `gen` value.) In the already existing fallback case, where the `fontName` is used to when creating the `font.loadedName`, we allow any alphanumeric character. Hence I don't see how (as mentioned above) e.g. `font.loadedName = g_d0_f4R` would be an issue here. --- src/core/evaluator.js | 47 ++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 47f5816b1..16dbc0b81 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -662,8 +662,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { return errorFont(); } - // We are holding font.translated references just for fontRef that are not - // dictionaries (Dict). See explanation below. + // We are holding `font.translated` references just for `fontRef`s that + // are not actually `Ref`s, but rather `Dict`s. See explanation below. if (font.translated) { return font.translated; } @@ -672,7 +672,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var preEvaluatedFont = this.preEvaluateFont(font, xref); var descriptor = preEvaluatedFont.descriptor; - var fontID = fontRef.num + '_' + fontRef.gen; + + var fontRefIsRef = isRef(fontRef), fontID; + if (fontRefIsRef) { + fontID = fontRef.toString(); + } + if (isDict(descriptor)) { if (!descriptor.fontAliases) { descriptor.fontAliases = Object.create(null); @@ -682,36 +687,40 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var hash = preEvaluatedFont.hash; if (fontAliases[hash]) { var aliasFontRef = fontAliases[hash].aliasRef; - if (aliasFontRef && this.fontCache.has(aliasFontRef)) { + if (fontRefIsRef && aliasFontRef && + this.fontCache.has(aliasFontRef)) { this.fontCache.putAlias(fontRef, aliasFontRef); return this.fontCache.get(fontRef); } - } - - if (!fontAliases[hash]) { + } else { fontAliases[hash] = { fontID: Font.getFontID() }; } - fontAliases[hash].aliasRef = fontRef; + if (fontRefIsRef) { + fontAliases[hash].aliasRef = fontRef; + } fontID = fontAliases[hash].fontID; } - // Workaround for bad PDF generators that don't reference fonts - // properly, i.e. by not using an object identifier. - // Check if the fontRef is a Dict (as opposed to a standard object), - // in which case we don't cache the font and instead reference it by - // fontName in font.loadedName below. - var fontRefIsDict = isDict(fontRef); - if (!fontRefIsDict) { + // Workaround for bad PDF generators that reference fonts incorrectly, + // where `fontRef` is a `Dict` rather than a `Ref` (fixes bug946506.pdf). + // In this case we cannot cache the font, since it's not possible to use + // a `Dict` as a key in `this.fontCache` (since it's a `RefSetCache`). + // Furthermore, if the `fontID` is undefined, we instead reference + // the font by `fontName` in `font.loadedName` below. + if (fontRefIsRef) { this.fontCache.put(fontRef, fontCapability.promise); + } else { + if (!fontID) { + fontID = (this.uniquePrefix || 'F_') + (++this.idCounters.obj); + } } // Keep track of each font we translated so the caller can // load them asynchronously before calling display on a page. - font.loadedName = 'g_' + this.pdfManager.docId + '_f' + (fontRefIsDict ? - fontName.replace(/\W/g, '') : fontID); + font.loadedName = 'g_' + this.pdfManager.docId + '_f' + fontID; font.translated = fontCapability.promise; @@ -2115,7 +2124,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { if (isName(encoding)) { hash.update(encoding.name); } else if (isRef(encoding)) { - hash.update(encoding.num + '_' + encoding.gen); + hash.update(encoding.toString()); } else if (isDict(encoding)) { var keys = encoding.getKeys(); for (var i = 0, ii = keys.length; i < ii; i++) { @@ -2123,7 +2132,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { if (isName(entry)) { hash.update(entry.name); } else if (isRef(entry)) { - hash.update(entry.num + '_' + entry.gen); + hash.update(entry.toString()); } else if (isArray(entry)) { // 'Differences' entry. // Ideally we should check the contents of the array, but to avoid // parsing it here and then again in |extractDataStructures|, From 4fe891c5e7fc533f4c73ec81ff4ccd4d250e07d7 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Mon, 13 Jun 2016 14:22:15 +0200 Subject: [PATCH 2/3] Add a reduced test-case for issue 7403 --- test/pdfs/.gitignore | 1 + test/pdfs/issue7403.pdf | Bin 0 -> 51871 bytes test/test_manifest.json | 7 +++++++ 3 files changed, 8 insertions(+) create mode 100644 test/pdfs/issue7403.pdf diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index fae8699b3..f61be7d3c 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -27,6 +27,7 @@ !issue7180.pdf !issue7200.pdf !issue7229.pdf +!issue7403.pdf !issue7426.pdf !issue7439.pdf !issue7492.pdf diff --git a/test/pdfs/issue7403.pdf b/test/pdfs/issue7403.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e5f53b510d9cdc75b9aacd72165fd4361cfc07e5 GIT binary patch literal 51871 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 literal 0 HcmV?d00001 diff --git a/test/test_manifest.json b/test/test_manifest.json index 4ae10fecd..973fb38eb 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -962,6 +962,13 @@ "rounds": 1, "type": "eq" }, + { "id": "issue7403", + "file": "pdfs/issue7403.pdf", + "md5": "0f7bb6b3c58e33bbf76ce5161cd665c3", + "link": false, + "rounds": 1, + "type": "eq" + }, { "id": "protectip", "file": "pdfs/protectip.pdf", "md5": "676e7a7b8f96d04825361832b1838a93", From 390c02a3e952945a8d112a6e3c4f2f15f820cbb9 Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Sat, 11 Jun 2016 14:28:59 +0200 Subject: [PATCH 3/3] Attempt to cache fonts that are direct objects (i.e. `Dict`s), as opposed to `Ref`s, to prevent re-rendering after `cleanup` from breaking (issue 7403 and issue 7402) Fonts that are not referenced by `Ref`s are very uncommon in practice, but it can unfortunately happen. In this case, we're currently not caching them in the usual way, i.e. by `Ref`, which leads to failures when a page is rendered after `cleanup` has run. The simplest solution would have been to remove the `font.translated` workaround, but since this would have meant loading these kind of fonts over and over, the patch attempts to be a bit clever about this situation. Note that if we instead loaded fonts per *page*, instead of per document, this issue wouldn't have existed. --- src/core/evaluator.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 16dbc0b81..c8f167be8 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -706,17 +706,30 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { // Workaround for bad PDF generators that reference fonts incorrectly, // where `fontRef` is a `Dict` rather than a `Ref` (fixes bug946506.pdf). - // In this case we cannot cache the font, since it's not possible to use - // a `Dict` as a key in `this.fontCache` (since it's a `RefSetCache`). - // Furthermore, if the `fontID` is undefined, we instead reference - // the font by `fontName` in `font.loadedName` below. + // In this case we should not put the font into `this.fontCache` (which is + // a `RefSetCache`), since it's not meaningful to use a `Dict` as a key. + // + // However, if we don't cache the font it's not possible to remove it + // when `cleanup` is triggered from the API, which causes issues on + // subsequent rendering operations (see issue7403.pdf). + // A simple workaround would be to just not hold `font.translated` + // references in this case, but this would force us to unnecessarily load + // the same fonts over and over. + // + // Instead, we cheat a bit by attempting to use a modified `fontID` as a + // key in `this.fontCache`, to allow the font to be cached. + // NOTE: This works because `RefSetCache` calls `toString()` on provided + // keys. Also, since `fontRef` is used when getting cached fonts, + // we'll not accidentally match fonts cached with the `fontID`. if (fontRefIsRef) { this.fontCache.put(fontRef, fontCapability.promise); } else { if (!fontID) { fontID = (this.uniquePrefix || 'F_') + (++this.idCounters.obj); } + this.fontCache.put('id_' + fontID, fontCapability.promise); } + assert(fontID, 'The "fontID" must be defined.'); // Keep track of each font we translated so the caller can // load them asynchronously before calling display on a page.