From 63b34114b114f91f990ab0d024c26d6458d2879e Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 22 Oct 2024 11:38:00 +0200 Subject: [PATCH 1/2] Fallback to a standard font if a font-file entry doesn't contain a Stream (issue 18941) The PDF document is clearly corrupt, since it has /FontFile2 entries that are Dictionaries which obviously isn't correct. While there's obviously no guarantee that things will look perfect this way, actually rendering the text at all should be an improvement in general. --- src/core/evaluator.js | 10 ++++++++++ test/pdfs/issue18941.pdf.link | 1 + test/test_manifest.json | 9 +++++++++ 3 files changed, 20 insertions(+) create mode 100644 test/pdfs/issue18941.pdf.link diff --git a/src/core/evaluator.js b/src/core/evaluator.js index c906abce558ab..1600f098a71ae 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -4436,6 +4436,16 @@ class PartialEvaluator { let glyphScaleFactors = null; let systemFontInfo = null; if (fontFile) { + if (!(fontFile instanceof BaseStream)) { + const msg = `Font file should be a Stream in "${fontName.name}".`; + + if (!this.options.ignoreErrors) { + throw new FormatError(msg); + } + warn(msg); + fontFile = new NullStream(); + } + if (fontFile.dict) { const subtypeEntry = fontFile.dict.get("Subtype"); if (subtypeEntry instanceof Name) { diff --git a/test/pdfs/issue18941.pdf.link b/test/pdfs/issue18941.pdf.link new file mode 100644 index 0000000000000..d2402e7405df0 --- /dev/null +++ b/test/pdfs/issue18941.pdf.link @@ -0,0 +1 @@ +https://github.com/user-attachments/files/17473385/21_10_2024_FAMI.INVERSION.SAS_901060703_inicial.pdf diff --git a/test/test_manifest.json b/test/test_manifest.json index 749cdf6c88c2f..38698ad8a4d03 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -2352,6 +2352,15 @@ "lastPage": 3, "type": "eq" }, + { + "id": "issue18941", + "file": "pdfs/issue18941.pdf", + "md5": "6288e69c1dd240859c1d49c22a53a5c7", + "rounds": 1, + "link": true, + "lastPage": 1, + "type": "eq" + }, { "id": "f1040", "file": "pdfs/f1040.pdf", From 236c8d862eb701cafcabdb8571f76c95425989ec Mon Sep 17 00:00:00 2001 From: Jonas Jenwald Date: Tue, 22 Oct 2024 16:41:53 +0200 Subject: [PATCH 2/2] Re-factor how we handle missing, corrupt, or empty font-file entries This improves the fixes for e.g. issue 9462 and 18941 slightly and allows better fallback behaviour for non-standard fonts. --- src/core/evaluator.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 1600f098a71ae..2828893474a8f 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -63,7 +63,6 @@ import { LocalTilingPatternCache, RegionalImageCache, } from "./image_utils.js"; -import { NullStream, Stream } from "./stream.js"; import { BaseStream } from "./base_stream.js"; import { bidi } from "./bidi.js"; import { ColorSpace } from "./colorspace.js"; @@ -77,6 +76,7 @@ import { ImageResizer } from "./image_resizer.js"; import { MurmurHash3_64 } from "../shared/murmurhash3.js"; import { OperatorList } from "./operator_list.js"; import { PDFImage } from "./image.js"; +import { Stream } from "./stream.js"; const DefaultPartialEvaluatorOptions = Object.freeze({ maxImageSize: -1, @@ -4425,27 +4425,25 @@ class PartialEvaluator { let fontFile, subtype, length1, length2, length3; try { fontFile = descriptor.get("FontFile", "FontFile2", "FontFile3"); + + if (fontFile) { + if (!(fontFile instanceof BaseStream)) { + throw new FormatError("FontFile should be a stream"); + } else if (fontFile.isEmpty) { + throw new FormatError("FontFile is empty"); + } + } } catch (ex) { if (!this.options.ignoreErrors) { throw ex; } warn(`translateFont - fetching "${fontName.name}" font file: "${ex}".`); - fontFile = new NullStream(); + fontFile = null; } let isInternalFont = false; let glyphScaleFactors = null; let systemFontInfo = null; if (fontFile) { - if (!(fontFile instanceof BaseStream)) { - const msg = `Font file should be a Stream in "${fontName.name}".`; - - if (!this.options.ignoreErrors) { - throw new FormatError(msg); - } - warn(msg); - fontFile = new NullStream(); - } - if (fontFile.dict) { const subtypeEntry = fontFile.dict.get("Subtype"); if (subtypeEntry instanceof Name) {