@@ -53,6 +53,76 @@ public static byte[] Decode(PdfDictionary dict, byte[] data, Dictionary<int, Pdf
5353 return current ;
5454 }
5555
56+ public static bool TryDecode ( PdfDictionary dict , byte [ ] data , int maxOutputBytes , out byte [ ] decoded , Dictionary < int , PdfIndirectObject > ? objects = null ) {
57+ decoded = Array . Empty < byte > ( ) ;
58+ if ( maxOutputBytes < 0 ) {
59+ return false ;
60+ }
61+
62+ if ( data == null || data . Length == 0 || ! dict . Items . TryGetValue ( "Filter" , out var filterObj ) ) {
63+ return TryUseOriginal ( data ?? Array . Empty < byte > ( ) , maxOutputBytes , out decoded ) ;
64+ }
65+
66+ byte [ ] original = data ;
67+ byte [ ] current = data ;
68+ int filterIndex = 0 ;
69+ foreach ( string filterName in EnumerateFilters ( filterObj , objects ) ) {
70+ try {
71+ switch ( GetFilterKind ( filterName ) ) {
72+ case DecodeFilterKind . Flate :
73+ if ( ! FlateDecoder . TryDecode ( current , maxOutputBytes , out current ) ) {
74+ return false ;
75+ }
76+
77+ current = ApplyDecodeParms ( dict , filterIndex , current , objects ) ;
78+ if ( ! IsWithinLimit ( current , maxOutputBytes ) ) {
79+ return false ;
80+ }
81+
82+ break ;
83+ case DecodeFilterKind . AsciiHex :
84+ current = AsciiHexDecoder . Decode ( current ) ;
85+ if ( ! IsWithinLimit ( current , maxOutputBytes ) ) {
86+ return false ;
87+ }
88+
89+ break ;
90+ case DecodeFilterKind . Ascii85 :
91+ current = Ascii85Decoder . Decode ( current ) ;
92+ if ( ! IsWithinLimit ( current , maxOutputBytes ) ) {
93+ return false ;
94+ }
95+
96+ break ;
97+ case DecodeFilterKind . RunLength :
98+ current = RunLengthDecoder . Decode ( current ) ;
99+ if ( ! IsWithinLimit ( current , maxOutputBytes ) ) {
100+ return false ;
101+ }
102+
103+ break ;
104+ case DecodeFilterKind . Lzw :
105+ current = LzwDecoder . Decode ( current , GetEarlyChange ( dict , filterIndex , objects ) ) ;
106+ current = ApplyDecodeParms ( dict , filterIndex , current , objects ) ;
107+ if ( ! IsWithinLimit ( current , maxOutputBytes ) ) {
108+ return false ;
109+ }
110+
111+ break ;
112+ default :
113+ return TryUseOriginal ( original , maxOutputBytes , out decoded ) ;
114+ }
115+ } catch {
116+ return TryUseOriginal ( original , maxOutputBytes , out decoded ) ;
117+ }
118+
119+ filterIndex ++ ;
120+ }
121+
122+ decoded = current ;
123+ return true ;
124+ }
125+
56126 internal static List < string > GetUnsupportedFilters ( PdfDictionary dict , Dictionary < int , PdfIndirectObject > ? objects = null ) {
57127 if ( ! dict . Items . TryGetValue ( "Filter" , out var filterObj ) ) {
58128 return new List < string > ( 0 ) ;
@@ -104,6 +174,20 @@ private static bool ContainsFilter(List<string> filters, string filterName) {
104174 return false ;
105175 }
106176
177+ private static bool TryUseOriginal ( byte [ ] data , int maxOutputBytes , out byte [ ] decoded ) {
178+ if ( ! IsWithinLimit ( data , maxOutputBytes ) ) {
179+ decoded = Array . Empty < byte > ( ) ;
180+ return false ;
181+ }
182+
183+ decoded = data ;
184+ return true ;
185+ }
186+
187+ private static bool IsWithinLimit ( byte [ ] data , int maxOutputBytes ) {
188+ return data . LongLength <= maxOutputBytes ;
189+ }
190+
107191 private static byte [ ] ApplyDecodeParms ( PdfDictionary dict , int filterIndex , byte [ ] data , Dictionary < int , PdfIndirectObject > ? objects ) {
108192 var decodeParms = GetDecodeParms ( dict , filterIndex , objects ) ;
109193 if ( decodeParms is null ) {
0 commit comments