@@ -6,164 +6,100 @@ namespace ICSharpCode.SharpZipLib.Zip.Compression
66 class InflaterDynHeader
77 {
88 #region Constants
9- const int LNUM = 0 ;
10- const int DNUM = 1 ;
11- const int BLNUM = 2 ;
12- const int BLLENS = 3 ;
13- const int LENS = 4 ;
14- const int REPS = 5 ;
15-
16- static readonly int [ ] repMin = { 3 , 3 , 11 } ;
17- static readonly int [ ] repBits = { 2 , 3 , 7 } ;
189
1910 static readonly int [ ] BL_ORDER =
2011 { 16 , 17 , 18 , 0 , 8 , 7 , 9 , 6 , 10 , 5 , 11 , 4 , 12 , 3 , 13 , 2 , 14 , 1 , 15 } ;
2112 #endregion
2213
2314 public bool Decode ( StreamManipulator input )
2415 {
25- decode_loop :
26- for ( ; ; ) {
27- switch ( mode ) {
28- case LNUM :
29- lnum = input . PeekBits ( 5 ) ;
30- if ( lnum < 0 ) {
31- return false ;
32- }
33- lnum += 257 ;
34- input . DropBits ( 5 ) ;
35- // System.err.println("LNUM: "+lnum);
36- mode = DNUM ;
37- goto case DNUM ; // fall through
38- case DNUM :
39- dnum = input . PeekBits ( 5 ) ;
40- if ( dnum < 0 ) {
41- return false ;
42- }
43- dnum ++ ;
44- input . DropBits ( 5 ) ;
45- // System.err.println("DNUM: "+dnum);
46- num = lnum + dnum ;
47- litdistLens = new byte [ num ] ;
48- mode = BLNUM ;
49- goto case BLNUM ; // fall through
50- case BLNUM :
51- blnum = input . PeekBits ( 4 ) ;
52- if ( blnum < 0 ) {
53- return false ;
54- }
55- blnum += 4 ;
56- input . DropBits ( 4 ) ;
57- blLens = new byte [ 19 ] ;
58- ptr = 0 ;
59- // System.err.println("BLNUM: "+blnum);
60- mode = BLLENS ;
61- goto case BLLENS ; // fall through
62- case BLLENS :
63- while ( ptr < blnum ) {
64- int len = input . PeekBits ( 3 ) ;
65- if ( len < 0 ) {
66- return false ;
67- }
68- input . DropBits ( 3 ) ;
69- // System.err.println("blLens["+BL_ORDER[ptr]+"]: "+len);
70- blLens [ BL_ORDER [ ptr ] ] = ( byte ) len ;
71- ptr ++ ;
16+ try
17+ {
18+ lnum = input . GrabBits ( 5 ) + 257 ;
19+ dnum = input . GrabBits ( 5 ) + 1 ;
20+ blnum = input . GrabBits ( 4 ) + 4 ;
21+ num = lnum + dnum ;
22+
23+ lengths = new byte [ 19 ] ;
24+
25+ for ( int i = 0 ; i < blnum ; i ++ )
26+ {
27+ lengths [ BL_ORDER [ i ] ] = ( byte ) input . GrabBits ( 3 , true ) ;
28+ }
29+ blTree = new InflaterHuffmanTree ( lengths ) ;
30+ lengths = new byte [ num ] ;
31+
32+ int index = 0 ;
33+ while ( index < lnum + dnum )
34+ {
35+ byte len ;
36+
37+ int symbol = blTree . GetSymbol ( input ) ;
38+ if ( symbol < 0 )
39+ return false ;
40+ if ( symbol < 16 )
41+ lengths [ index ++ ] = ( byte ) symbol ;
42+ else
43+ {
44+ len = 0 ;
45+ if ( symbol == 16 )
46+ {
47+ if ( index == 0 )
48+ return false ; // No last length!
49+ len = lengths [ index - 1 ] ;
50+ symbol = input . GrabBits ( 2 , true ) + 3 ;
7251 }
73- blTree = new InflaterHuffmanTree ( blLens ) ;
74- blLens = null ;
75- ptr = 0 ;
76- mode = LENS ;
77- goto case LENS ; // fall through
78- case LENS : {
79- int symbol ;
80- while ( ( ( symbol = blTree . GetSymbol ( input ) ) & ~ 15 ) == 0 ) {
81- /* Normal case: symbol in [0..15] */
82-
83- // System.err.println("litdistLens["+ptr+"]: "+symbol);
84- litdistLens [ ptr ++ ] = lastLen = ( byte ) symbol ;
85-
86- if ( ptr == num ) {
87- /* Finished */
88- return true ;
89- }
90- }
91-
92- /* need more input ? */
93- if ( symbol < 0 ) {
94- return false ;
95- }
96-
97- /* otherwise repeat code */
98- if ( symbol >= 17 ) {
99- /* repeat zero */
100- // System.err.println("repeating zero");
101- lastLen = 0 ;
102- } else {
103- if ( ptr == 0 ) {
104- throw new SharpZipBaseException ( ) ;
105- }
106- }
107- repSymbol = symbol - 16 ;
52+ else if ( symbol == 17 )
53+ {
54+ // repeat zero 3..10 times
55+ symbol = input . GrabBits ( 3 , true ) + 3 ;
10856 }
109- mode = REPS ;
110- goto case REPS ; // fall through
111- case REPS : {
112- int bits = repBits [ repSymbol ] ;
113- int count = input . PeekBits ( bits ) ;
114- if ( count < 0 ) {
115- return false ;
116- }
117- input . DropBits ( bits ) ;
118- count += repMin [ repSymbol ] ;
119- // System.err.println("litdistLens repeated: "+count);
120-
121- if ( ptr + count > num ) {
122- throw new SharpZipBaseException ( ) ;
123- }
124- while ( count -- > 0 ) {
125- litdistLens [ ptr ++ ] = lastLen ;
126- }
127-
128- if ( ptr == num ) {
129- /* Finished */
130- return true ;
131- }
57+ else
58+ {
59+ // (symbol == 18), repeat zero 11..138 times
60+ symbol = input . GrabBits ( 7 , true ) + 11 ;
13261 }
133- mode = LENS ;
134- goto decode_loop ;
62+
63+ if ( index + symbol > lnum + dnum )
64+ return false ; // too many lengths!
65+
66+ // repeat last or zero symbol times
67+ while ( symbol -- > 0 )
68+ lengths [ index ++ ] = len ;
69+ }
13570 }
71+
72+ if ( lengths [ 256 ] == 0 )
73+ return false ; // No end-of-block code!
74+
75+ return true ;
76+ }
77+ catch ( Exception x )
78+ {
79+ return false ;
13680 }
13781 }
13882
13983 public InflaterHuffmanTree BuildLitLenTree ( )
14084 {
14185 byte [ ] litlenLens = new byte [ lnum ] ;
142- Array . Copy ( litdistLens , 0 , litlenLens , 0 , lnum ) ;
86+ Array . Copy ( lengths , 0 , litlenLens , 0 , lnum ) ;
14387 return new InflaterHuffmanTree ( litlenLens ) ;
14488 }
14589
14690 public InflaterHuffmanTree BuildDistTree ( )
14791 {
14892 byte [ ] distLens = new byte [ dnum ] ;
149- Array . Copy ( litdistLens , lnum , distLens , 0 , dnum ) ;
93+ Array . Copy ( lengths , lnum , distLens , 0 , dnum ) ;
15094 return new InflaterHuffmanTree ( distLens ) ;
15195 }
15296
15397 #region Instance Fields
154- byte [ ] blLens ;
155- byte [ ] litdistLens ;
98+ byte [ ] lengths ;
15699
157100 InflaterHuffmanTree blTree ;
158101
159- /// <summary>
160- /// The current decode mode
161- /// </summary>
162- int mode ;
163102 int lnum , dnum , blnum , num ;
164- int repSymbol ;
165- byte lastLen ;
166- int ptr ;
167103 #endregion
168104
169105 }
0 commit comments