@@ -66,7 +66,7 @@ public static Memory<byte> Decode(this StreamToken stream, IFilterProvider filte
6666 {
6767 var filter = filters [ i ] ;
6868 totalMaxEstSize *= GetEstimatedSizeMultiplier ( filter ) ;
69-
69+
7070 transform = filter . Decode ( transform , stream . StreamDictionary , filterProvider , i ) ;
7171
7272 if ( i < filters . Count - 1 && transform . Length > totalMaxEstSize )
@@ -93,9 +93,9 @@ public static Memory<byte> Decode(this StreamToken stream, ILookupFilterProvider
9393 {
9494 var filter = filters [ i ] ;
9595 totalMaxEstSize *= GetEstimatedSizeMultiplier ( filter ) ;
96-
96+
9797 transform = filter . Decode ( transform , stream . StreamDictionary , filterProvider , i ) ;
98-
98+
9999 if ( i < filters . Count - 1 && transform . Length > totalMaxEstSize )
100100 {
101101 // Try to prevent malicious decompression, leading to OOM issues
@@ -122,25 +122,34 @@ private static double GetEstimatedSizeMultiplier(IFilter filter)
122122 /// Returns an equivalent token where any indirect references of child objects are
123123 /// recursively traversed and resolved.
124124 /// </summary>
125- internal static T ? Resolve < T > ( this T ? token , IPdfTokenScanner scanner ) where T : IToken
125+ internal static T ? Resolve < T > ( this T ? token , IPdfTokenScanner scanner , List < long > ? visited = null ) where T : IToken
126126 {
127- return ( T ? ) ResolveInternal ( token , scanner ) ;
127+ return ( T ? ) ResolveInternal ( token , scanner , visited ?? [ ] ) ;
128128 }
129129
130- private static IToken ? ResolveInternal ( this IToken ? token , IPdfTokenScanner scanner )
130+ private static IToken ? ResolveInternal ( this IToken ? token , IPdfTokenScanner scanner , List < long > visited )
131131 {
132132 if ( token is StreamToken stream )
133133 {
134- return new StreamToken ( Resolve ( stream . StreamDictionary , scanner ) , stream . Data ) ;
134+ return new StreamToken ( Resolve ( stream . StreamDictionary , scanner , visited ) , stream . Data ) ;
135135 }
136136
137137 if ( token is DictionaryToken dict )
138138 {
139139 var resolvedItems = new Dictionary < NameToken , IToken > ( ) ;
140140 foreach ( var kvp in dict . Data )
141141 {
142- var value = kvp . Value is IndirectReferenceToken reference ? scanner . Get ( reference . Data ) ? . Data : kvp . Value ;
143- resolvedItems [ NameToken . Create ( kvp . Key ) ] = ResolveInternal ( value , scanner ) ;
142+ var value = kvp . Value ;
143+ if ( kvp . Value is IndirectReferenceToken reference )
144+ {
145+ if ( visited . Contains ( reference . Data . ObjectNumber ) )
146+ {
147+ continue ;
148+ }
149+ value = scanner . Get ( reference . Data ) ? . Data ;
150+ visited . Add ( reference . Data . ObjectNumber ) ;
151+ }
152+ resolvedItems [ NameToken . Create ( kvp . Key ) ] = ResolveInternal ( value , scanner , visited ) ;
144153 }
145154
146155 return new DictionaryToken ( resolvedItems ) ;
@@ -152,7 +161,7 @@ private static double GetEstimatedSizeMultiplier(IFilter filter)
152161 for ( int i = 0 ; i < arr . Length ; i ++ )
153162 {
154163 var value = arr . Data [ i ] is IndirectReferenceToken reference ? scanner . Get ( reference . Data ) ? . Data : arr . Data [ i ] ;
155- resolvedItems . Add ( ResolveInternal ( value , scanner ) ) ;
164+ resolvedItems . Add ( ResolveInternal ( value , scanner , visited ) ) ;
156165 }
157166 return new ArrayToken ( resolvedItems ) ;
158167 }
0 commit comments