Prevent circular references in Type3 fonts
In corrupt PDF documents Type3 fonts may introduce circular dependencies, thus resulting in the affected font(s) never loading and parsing/rendering never completing. Note that I've not seen any real-world examples of this kind of font corruption, but the attached PDF document was rather found in https://github.com/pdf-association/safedocs/tree/main/Miscellaneous%20Targeted%20Test%20PDFs *Please note:* That repository contains a number of reduced test-cases that are specifically intended to test interoperability (between PDF viewer) and parsing/rendering for various kinds of strange/corrupt PDF documents. Some of the test-cases found there may thus not make sense to try and "fix" upfront, in my opinion, unless the problems are also found in real-world PDF documents.
This commit is contained in:
		
							parent
							
								
									ea57ef116e
								
							
						
					
					
						commit
						53d4ee7990
					
				@ -1155,6 +1155,10 @@ class PartialEvaluator {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (this.parsingType3Font && this.type3FontRefs.has(fontRef)) {
 | 
				
			||||||
 | 
					      return errorFont();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (this.fontCache.has(fontRef)) {
 | 
					    if (this.fontCache.has(fontRef)) {
 | 
				
			||||||
      return this.fontCache.get(fontRef);
 | 
					      return this.fontCache.get(fontRef);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -4183,6 +4187,12 @@ class TranslatedFont {
 | 
				
			|||||||
    // make sense to only be able to render a Type3 glyph partially.
 | 
					    // make sense to only be able to render a Type3 glyph partially.
 | 
				
			||||||
    const type3Evaluator = evaluator.clone({ ignoreErrors: false });
 | 
					    const type3Evaluator = evaluator.clone({ ignoreErrors: false });
 | 
				
			||||||
    type3Evaluator.parsingType3Font = true;
 | 
					    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,
 | 
					    const translatedFont = this.font,
 | 
				
			||||||
      type3Dependencies = this.type3Dependencies;
 | 
					      type3Dependencies = this.type3Dependencies;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								test/pdfs/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								test/pdfs/.gitignore
									
									
									
									
										vendored
									
									
								
							@ -217,6 +217,7 @@
 | 
				
			|||||||
!issue7339_reduced.pdf
 | 
					!issue7339_reduced.pdf
 | 
				
			||||||
!issue3438.pdf
 | 
					!issue3438.pdf
 | 
				
			||||||
!issue11403_reduced.pdf
 | 
					!issue11403_reduced.pdf
 | 
				
			||||||
 | 
					!ContentStreamCycleType3insideType3.pdf
 | 
				
			||||||
!issue2074.pdf
 | 
					!issue2074.pdf
 | 
				
			||||||
!scan-bad.pdf
 | 
					!scan-bad.pdf
 | 
				
			||||||
!issue13561_reduced.pdf
 | 
					!issue13561_reduced.pdf
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										122
									
								
								test/pdfs/ContentStreamCycleType3insideType3.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										122
									
								
								test/pdfs/ContentStreamCycleType3insideType3.pdf
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,122 @@
 | 
				
			|||||||
 | 
					%PDF-1.6
 | 
				
			||||||
 | 
					%µ¶
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1 0 obj
 | 
				
			||||||
 | 
					<</Type/Catalog/Outlines 2 0 R/Pages 3 0 R>>
 | 
				
			||||||
 | 
					endobj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					2 0 obj
 | 
				
			||||||
 | 
					<</Type/Outlines/Count 0>>
 | 
				
			||||||
 | 
					endobj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					3 0 obj
 | 
				
			||||||
 | 
					<</Type/Pages/Kids[4 0 R]/Count 1>>
 | 
				
			||||||
 | 
					endobj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					4 0 obj
 | 
				
			||||||
 | 
					<</Type/Page/Parent 3 0 R/MediaBox[0 0 600 840]/Contents 5 0 R/Resources<</Font<</FType3A 6 0 R>>>>>>
 | 
				
			||||||
 | 
					endobj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					5 0 obj
 | 
				
			||||||
 | 
					<</Length 123>>
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					<</Type/Font/Subtype/Type3/Name/FType3A/Widths[1000 1000]/FontBBox[0 0 750 750]/FontMatrix[.01 0 0 .01 0 0]/Encoding<</Type/Encoding/Differences[97/rect/triangle]>>/Resources<</Font<</FType3B 9 0 R>>>>/CharProcs<</rect 7 0 R/triangle 8 0 R>>/FirstChar 97/LastChar 98>>
 | 
				
			||||||
 | 
					endobj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					7 0 obj
 | 
				
			||||||
 | 
					<</Length 179>>
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					<</Length 99>>
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					<</Type/Font/Subtype/Type3/Name/FType3B/FontBBox[0 0 750 750]/FontMatrix[.004 0 0 .004 0 0]/Encoding<</Type/Encoding/Differences[99/fontinside]>>/Widths[900]/Resources<</Font<</F1 11 0 R>>/Pattern<</P1 12 0 R>>>>/CharProcs<</fontinside 10 0 R>>/FirstChar 99/LastChar 99>>
 | 
				
			||||||
 | 
					endobj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					10 0 obj
 | 
				
			||||||
 | 
					<</Length 265>>
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					<</Type/Font/Subtype/Type1/BaseFont/Helvetica>>
 | 
				
			||||||
 | 
					endobj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					12 0 obj
 | 
				
			||||||
 | 
					<</Type/Pattern/PaintType 1/PatternType 1/TilingType 2/Matrix[0.9 0 0 0.9 0 0]/XStep 55/YStep 32/BBox[0 0 60 60]/Resources<</Font<</CyclicFont  6 0 R>>>>/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
 | 
				
			||||||
 | 
					<</Size 13/Root 1 0 R>>
 | 
				
			||||||
 | 
					startxref
 | 
				
			||||||
 | 
					2111
 | 
				
			||||||
 | 
					%%EOF
 | 
				
			||||||
@ -4537,6 +4537,12 @@
 | 
				
			|||||||
       "lastPage": 3,
 | 
					       "lastPage": 3,
 | 
				
			||||||
       "type": "eq"
 | 
					       "type": "eq"
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    {  "id": "ContentStreamCycleType3insideType3",
 | 
				
			||||||
 | 
					       "file": "pdfs/ContentStreamCycleType3insideType3.pdf",
 | 
				
			||||||
 | 
					       "md5": "64840fc5dd8ca06afbc86477d9121b59",
 | 
				
			||||||
 | 
					       "rounds": 1,
 | 
				
			||||||
 | 
					       "type": "eq"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    { "id": "issue3458.pdf",
 | 
					    { "id": "issue3458.pdf",
 | 
				
			||||||
      "file": "pdfs/issue3458.pdf",
 | 
					      "file": "pdfs/issue3458.pdf",
 | 
				
			||||||
      "md5": "dab8bd3ad1acfc8dc82a8381a3c8ff94",
 | 
					      "md5": "dab8bd3ad1acfc8dc82a8381a3c8ff94",
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user