diff --git a/src/core/evaluator.js b/src/core/evaluator.js index 3e0dd8492..606208d8f 100644 --- a/src/core/evaluator.js +++ b/src/core/evaluator.js @@ -1155,6 +1155,10 @@ class PartialEvaluator { } } + if (this.parsingType3Font && this.type3FontRefs.has(fontRef)) { + return errorFont(); + } + if (this.fontCache.has(fontRef)) { return this.fontCache.get(fontRef); } @@ -4183,6 +4187,12 @@ class TranslatedFont { // make sense to only be able to render a Type3 glyph partially. const type3Evaluator = evaluator.clone({ ignoreErrors: false }); type3Evaluator.parsingType3Font = true; + // Prevent circular references in Type3 fonts. + const type3FontRefs = new RefSet(evaluator.type3FontRefs); + if (this.dict.objId && !type3FontRefs.has(this.dict.objId)) { + type3FontRefs.put(this.dict.objId); + } + type3Evaluator.type3FontRefs = type3FontRefs; const translatedFont = this.font, type3Dependencies = this.type3Dependencies; diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index e9067c31c..6342c70ad 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -217,6 +217,7 @@ !issue7339_reduced.pdf !issue3438.pdf !issue11403_reduced.pdf +!ContentStreamCycleType3insideType3.pdf !issue2074.pdf !scan-bad.pdf !issue13561_reduced.pdf diff --git a/test/pdfs/ContentStreamCycleType3insideType3.pdf b/test/pdfs/ContentStreamCycleType3insideType3.pdf new file mode 100644 index 000000000..d6e67741e --- /dev/null +++ b/test/pdfs/ContentStreamCycleType3insideType3.pdf @@ -0,0 +1,122 @@ +%PDF-1.6 +%µ¶ + +1 0 obj +<> +endobj + +2 0 obj +<> +endobj + +3 0 obj +<> +endobj + +4 0 obj +<>>>>> +endobj + +5 0 obj +<> +stream +BT + 1 0 0 1 100 500 Tm + 2 Tr % Fill then Stroke Text render mode + /FType3A 20 Tf + 20 20 Td + 50 Tw + (ab) Tj +ET +endstream +endobj + +6 0 obj +<>/Resources<>>>/CharProcs<>/FirstChar 97/LastChar 98>> +endobj + +7 0 obj +<> +stream +%%% FType3A stroked red 'rect' = 97 or 'a' +1000 0 d0 +20 w +1 0 0 RG +0 0 750 750 re s +BT % This is where a Type3 calls into another Type 3! + /FType3B 50 Tf + (ccc) Tj +ET +endstream +endobj + +8 0 obj +<> +stream +%%% FType3A stroked green 'triangle' = 98 'b' +1000 0 d0 +20 w +0 1 0 RG +0 0 m 375 750 l 750 0 l s +endstream +endobj + +9 0 obj +<>/Widths[900]/Resources<>/Pattern<>>>/CharProcs<>/FirstChar 99/LastChar 99>> +endobj + +10 0 obj +<> +stream +900 0 d0 +%%% FType3B Helv text for 'c' +2 Tr % Fill then Stroke Text render mode +10 w % stroke width 10 +0 0 1 RG % Blue stroke +/Pattern cs /P1 scn % Set /P1 pattern as fill (magenta text) +BT + /F1 60 Tf + 30 0 0 30 15 15 Tm -3 Tc 0 Tw + (ab) Tj +ET +endstream +endobj + +11 0 obj +<> +endobj + +12 0 obj +<>>>/Length 100>> +stream +BT + /CyclicFont 4 Tf + 10 0 0 10 1 1 Tm + 0 Tc + 0 Tw + 1 0 1 rg % Magenta fill + (ba) Tj +ET +endstream +endobj + +xref +0 13 +0000000000 65536 f +0000000016 00000 n +0000000077 00000 n +0000000120 00000 n +0000000172 00000 n +0000000290 00000 n +0000000464 00000 n +0000000749 00000 n +0000000978 00000 n +0000001127 00000 n +0000001419 00000 n +0000001736 00000 n +0000001802 00000 n +trailer +<> +startxref +2111 +%%EOF diff --git a/test/test_manifest.json b/test/test_manifest.json index f95c0eb3a..8c810f3b7 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -4537,6 +4537,12 @@ "lastPage": 3, "type": "eq" }, + { "id": "ContentStreamCycleType3insideType3", + "file": "pdfs/ContentStreamCycleType3insideType3.pdf", + "md5": "64840fc5dd8ca06afbc86477d9121b59", + "rounds": 1, + "type": "eq" + }, { "id": "issue3458.pdf", "file": "pdfs/issue3458.pdf", "md5": "dab8bd3ad1acfc8dc82a8381a3c8ff94",