Mercurial > 510Connectbot
comparison src/com/jcraft/jzlib/Inflate.java @ 357:46c2115ae1c8
update jzlib to a21be20213d66eff15904d925e9b721956a01ef7
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Fri, 01 Aug 2014 13:34:58 -0700 |
parents | 0ce5cc452d02 |
children |
comparison
equal
deleted
inserted
replaced
356:5e91b559b5fe | 357:46c2115ae1c8 |
---|---|
1 /* -*-mode:java; c-basic-offset:2; -*- */ | 1 /* -*-mode:java; c-basic-offset:2; -*- */ |
2 /* | 2 /* |
3 Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. | 3 Copyright (c) 2000-2011 ymnk, JCraft,Inc. All rights reserved. |
4 | 4 |
5 Redistribution and use in source and binary forms, with or without | 5 Redistribution and use in source and binary forms, with or without |
6 modification, are permitted provided that the following conditions are met: | 6 modification, are permitted provided that the following conditions are met: |
7 | 7 |
8 1. Redistributions of source code must retain the above copyright notice, | 8 1. Redistributions of source code must retain the above copyright notice, |
9 this list of conditions and the following disclaimer. | 9 this list of conditions and the following disclaimer. |
10 | 10 |
11 2. Redistributions in binary form must reproduce the above copyright | 11 2. Redistributions in binary form must reproduce the above copyright |
12 notice, this list of conditions and the following disclaimer in | 12 notice, this list of conditions and the following disclaimer in |
13 the documentation and/or other materials provided with the distribution. | 13 the documentation and/or other materials provided with the distribution. |
14 | 14 |
15 3. The names of the authors may not be used to endorse or promote products | 15 3. The names of the authors may not be used to endorse or promote products |
16 derived from this software without specific prior written permission. | 16 derived from this software without specific prior written permission. |
17 | 17 |
32 * and contributors of zlib. | 32 * and contributors of zlib. |
33 */ | 33 */ |
34 | 34 |
35 package com.jcraft.jzlib; | 35 package com.jcraft.jzlib; |
36 | 36 |
37 final class Inflate { | 37 final class Inflate{ |
38 | 38 |
39 static final private int MAX_WBITS = 15; // 32K LZ77 window | 39 static final private int MAX_WBITS=15; // 32K LZ77 window |
40 | 40 |
41 // preset dictionary flag in zlib header | 41 // preset dictionary flag in zlib header |
42 static final private int PRESET_DICT = 0x20; | 42 static final private int PRESET_DICT=0x20; |
43 | 43 |
44 static final int Z_NO_FLUSH = 0; | 44 static final int Z_NO_FLUSH=0; |
45 static final int Z_PARTIAL_FLUSH = 1; | 45 static final int Z_PARTIAL_FLUSH=1; |
46 static final int Z_SYNC_FLUSH = 2; | 46 static final int Z_SYNC_FLUSH=2; |
47 static final int Z_FULL_FLUSH = 3; | 47 static final int Z_FULL_FLUSH=3; |
48 static final int Z_FINISH = 4; | 48 static final int Z_FINISH=4; |
49 | 49 |
50 static final private int Z_DEFLATED = 8; | 50 static final private int Z_DEFLATED=8; |
51 | 51 |
52 static final private int Z_OK = 0; | 52 static final private int Z_OK=0; |
53 static final private int Z_STREAM_END = 1; | 53 static final private int Z_STREAM_END=1; |
54 static final private int Z_NEED_DICT = 2; | 54 static final private int Z_NEED_DICT=2; |
55 static final private int Z_ERRNO = -1; | 55 static final private int Z_ERRNO=-1; |
56 static final private int Z_STREAM_ERROR = -2; | 56 static final private int Z_STREAM_ERROR=-2; |
57 static final private int Z_DATA_ERROR = -3; | 57 static final private int Z_DATA_ERROR=-3; |
58 static final private int Z_MEM_ERROR = -4; | 58 static final private int Z_MEM_ERROR=-4; |
59 static final private int Z_BUF_ERROR = -5; | 59 static final private int Z_BUF_ERROR=-5; |
60 static final private int Z_VERSION_ERROR = -6; | 60 static final private int Z_VERSION_ERROR=-6; |
61 | 61 |
62 static final private int METHOD = 0; // waiting for method byte | 62 static final private int METHOD=0; // waiting for method byte |
63 static final private int FLAG = 1; // waiting for flag byte | 63 static final private int FLAG=1; // waiting for flag byte |
64 static final private int DICT4 = 2; // four dictionary check bytes to go | 64 static final private int DICT4=2; // four dictionary check bytes to go |
65 static final private int DICT3 = 3; // three dictionary check bytes to go | 65 static final private int DICT3=3; // three dictionary check bytes to go |
66 static final private int DICT2 = 4; // two dictionary check bytes to go | 66 static final private int DICT2=4; // two dictionary check bytes to go |
67 static final private int DICT1 = 5; // one dictionary check byte to go | 67 static final private int DICT1=5; // one dictionary check byte to go |
68 static final private int DICT0 = 6; // waiting for inflateSetDictionary | 68 static final private int DICT0=6; // waiting for inflateSetDictionary |
69 static final private int BLOCKS = 7; // decompressing blocks | 69 static final private int BLOCKS=7; // decompressing blocks |
70 static final private int CHECK4 = 8; // four check bytes to go | 70 static final private int CHECK4=8; // four check bytes to go |
71 static final private int CHECK3 = 9; // three check bytes to go | 71 static final private int CHECK3=9; // three check bytes to go |
72 static final private int CHECK2 = 10; // two check bytes to go | 72 static final private int CHECK2=10; // two check bytes to go |
73 static final private int CHECK1 = 11; // one check byte to go | 73 static final private int CHECK1=11; // one check byte to go |
74 static final private int DONE = 12; // finished check, done | 74 static final private int DONE=12; // finished check, done |
75 static final private int BAD = 13; // got an error--stay here | 75 static final private int BAD=13; // got an error--stay here |
76 | 76 |
77 int mode; // current inflate mode | 77 static final private int HEAD=14; |
78 | 78 static final private int LENGTH=15; |
79 // mode dependent information | 79 static final private int TIME=16; |
80 int method; // if FLAGS, method byte | 80 static final private int OS=17; |
81 | 81 static final private int EXLEN=18; |
82 // if CHECK, check values to compare | 82 static final private int EXTRA=19; |
83 long[] was = new long[1] ; // computed check value | 83 static final private int NAME=20; |
84 long need; // stream check value | 84 static final private int COMMENT=21; |
85 | 85 static final private int HCRC=22; |
86 // if BAD, inflateSync's marker bytes count | 86 static final private int FLAGS=23; |
87 int marker; | 87 |
88 | 88 static final int INFLATE_ANY=0x40000000; |
89 // mode independent information | 89 |
90 int nowrap; // flag for no wrapper | 90 int mode; // current inflate mode |
91 int wbits; // log2(window size) (8..15, defaults to 15) | 91 |
92 | 92 // mode dependent information |
93 InfBlocks blocks; // current inflate_blocks state | 93 int method; // if FLAGS, method byte |
94 | 94 |
95 int inflateReset(ZStream z) { | 95 // if CHECK, check values to compare |
96 if (z == null || z.istate == null) return Z_STREAM_ERROR; | 96 long was = -1; // computed check value |
97 | 97 long need; // stream check value |
98 z.total_in = z.total_out = 0; | 98 |
99 z.msg = null; | 99 // if BAD, inflateSync's marker bytes count |
100 z.istate.mode = z.istate.nowrap != 0 ? BLOCKS : METHOD; | 100 int marker; |
101 z.istate.blocks.reset(z, null); | 101 |
102 return Z_OK; | 102 // mode independent information |
103 } | 103 int wrap; // flag for no wrapper |
104 | 104 // 0: no wrapper |
105 int inflateEnd(ZStream z) { | 105 // 1: zlib header |
106 if (blocks != null) | 106 // 2: gzip header |
107 blocks.free(z); | 107 // 4: auto detection |
108 | 108 |
109 blocks = null; | 109 int wbits; // log2(window size) (8..15, defaults to 15) |
110 // ZFREE(z, z->state); | 110 |
111 return Z_OK; | 111 InfBlocks blocks; // current inflate_blocks state |
112 } | 112 |
113 | 113 private final ZStream z; |
114 int inflateInit(ZStream z, int w) { | 114 |
115 z.msg = null; | 115 private int flags; |
116 blocks = null; | 116 |
117 // handle undocumented nowrap option (no zlib header or check) | 117 private int need_bytes = -1; |
118 nowrap = 0; | 118 private byte[] crcbuf=new byte[4]; |
119 | 119 |
120 if (w < 0) { | 120 GZIPHeader gheader = null; |
121 w = - w; | 121 |
122 nowrap = 1; | 122 int inflateReset(){ |
123 } | 123 if(z == null) return Z_STREAM_ERROR; |
124 | 124 |
125 // set window size | 125 z.total_in = z.total_out = 0; |
126 if (w < 8 || w > 15) { | 126 z.msg = null; |
127 inflateEnd(z); | 127 this.mode = HEAD; |
128 return Z_STREAM_ERROR; | 128 this.need_bytes = -1; |
129 } | 129 this.blocks.reset(); |
130 | 130 return Z_OK; |
131 wbits = w; | 131 } |
132 z.istate.blocks = new InfBlocks(z, | 132 |
133 z.istate.nowrap != 0 ? null : this, | 133 int inflateEnd(){ |
134 1 << w); | 134 if(blocks != null){ |
135 // reset state | 135 blocks.free(); |
136 inflateReset(z); | 136 } |
137 return Z_OK; | 137 return Z_OK; |
138 } | 138 } |
139 | 139 |
140 int inflate(ZStream z, int f) { | 140 Inflate(ZStream z){ |
141 int r; | 141 this.z=z; |
142 int b; | 142 } |
143 | 143 |
144 if (z == null || z.istate == null || z.next_in == null) | 144 int inflateInit(int w){ |
145 return Z_STREAM_ERROR; | 145 z.msg = null; |
146 | 146 blocks = null; |
147 f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; | 147 |
148 r = Z_BUF_ERROR; | 148 // handle undocumented wrap option (no zlib header or check) |
149 | 149 wrap = 0; |
150 while (true) { | 150 if(w < 0){ |
151 //System.out.println("mode: "+z.istate.mode); | 151 w = - w; |
152 switch (z.istate.mode) { | 152 } |
153 case METHOD: | 153 else if((w&INFLATE_ANY) != 0){ |
154 if (z.avail_in == 0)return r; r = f; | 154 wrap = 4; |
155 | 155 w &= ~INFLATE_ANY; |
156 z.avail_in--; z.total_in++; | 156 if(w < 48) |
157 | 157 w &= 15; |
158 if (((z.istate.method = z.next_in[z.next_in_index++]) & 0xf) != Z_DEFLATED) { | 158 } |
159 z.istate.mode = BAD; | 159 else if((w & ~31) != 0) { // for example, DEF_WBITS + 32 |
160 z.msg = "unknown compression method"; | 160 wrap = 4; // zlib and gzip wrapped data should be accepted. |
161 z.istate.marker = 5; // can't try inflateSync | 161 w &= 15; |
162 break; | 162 } |
163 } | 163 else { |
164 | 164 wrap = (w >> 4) + 1; |
165 if ((z.istate.method >> 4) + 8 > z.istate.wbits) { | 165 if(w < 48) |
166 z.istate.mode = BAD; | 166 w &= 15; |
167 z.msg = "invalid window size"; | 167 } |
168 z.istate.marker = 5; // can't try inflateSync | 168 |
169 break; | 169 if(w<8 ||w>15){ |
170 } | 170 inflateEnd(); |
171 | 171 return Z_STREAM_ERROR; |
172 z.istate.mode = FLAG; | 172 } |
173 | 173 if(blocks != null && wbits != w){ |
174 case FLAG: | 174 blocks.free(); |
175 if (z.avail_in == 0)return r; r = f; | 175 blocks=null; |
176 | 176 } |
177 z.avail_in--; z.total_in++; | 177 |
178 b = (z.next_in[z.next_in_index++]) & 0xff; | 178 // set window size |
179 | 179 wbits=w; |
180 if ((((z.istate.method << 8) + b) % 31) != 0) { | 180 |
181 z.istate.mode = BAD; | 181 this.blocks=new InfBlocks(z, 1<<w); |
182 z.msg = "incorrect header check"; | 182 |
183 z.istate.marker = 5; // can't try inflateSync | 183 // reset state |
184 break; | 184 inflateReset(); |
185 } | 185 |
186 | 186 return Z_OK; |
187 if ((b & PRESET_DICT) == 0) { | 187 } |
188 z.istate.mode = BLOCKS; | 188 |
189 break; | 189 int inflate(int f){ |
190 } | 190 int hold = 0; |
191 | 191 |
192 z.istate.mode = DICT4; | 192 int r; |
193 | 193 int b; |
194 case DICT4: | 194 |
195 if (z.avail_in == 0)return r; r = f; | 195 if(z == null || z.next_in == null){ |
196 | 196 if(f == Z_FINISH && this.mode==HEAD) |
197 z.avail_in--; z.total_in++; | 197 return Z_OK; |
198 z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000L; | 198 return Z_STREAM_ERROR; |
199 z.istate.mode = DICT3; | 199 } |
200 | 200 |
201 case DICT3: | 201 f = f == Z_FINISH ? Z_BUF_ERROR : Z_OK; |
202 if (z.avail_in == 0)return r; r = f; | 202 r = Z_BUF_ERROR; |
203 | 203 while (true){ |
204 z.avail_in--; z.total_in++; | 204 |
205 z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L; | 205 switch (this.mode){ |
206 z.istate.mode = DICT2; | 206 case HEAD: |
207 | 207 if(wrap==0){ |
208 case DICT2: | 208 this.mode = BLOCKS; |
209 if (z.avail_in == 0)return r; r = f; | 209 break; |
210 | 210 } |
211 z.avail_in--; z.total_in++; | 211 |
212 z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L; | 212 try { r=readBytes(2, r, f); } |
213 z.istate.mode = DICT1; | 213 catch(Return e){ return e.r; } |
214 | 214 |
215 case DICT1: | 215 if((wrap == 4 || (wrap&2)!=0) && |
216 if (z.avail_in == 0)return r; r = f; | 216 this.need == 0x8b1fL) { // gzip header |
217 | 217 if(wrap == 4){ |
218 z.avail_in--; z.total_in++; | 218 wrap = 2; |
219 z.istate.need += (z.next_in[z.next_in_index++] & 0xffL); | 219 } |
220 z.adler = z.istate.need; | 220 z.adler=new CRC32(); |
221 z.istate.mode = DICT0; | 221 checksum(2, this.need); |
222 return Z_NEED_DICT; | 222 |
223 | 223 if(gheader==null) |
224 case DICT0: | 224 gheader=new GZIPHeader(); |
225 z.istate.mode = BAD; | 225 |
226 z.msg = "need dictionary"; | 226 this.mode = FLAGS; |
227 z.istate.marker = 0; // can try inflateSync | 227 break; |
228 return Z_STREAM_ERROR; | 228 } |
229 | 229 |
230 case BLOCKS: | 230 if((wrap&2) != 0){ |
231 r = z.istate.blocks.proc(z, r); | 231 this.mode = BAD; |
232 | 232 z.msg = "incorrect header check"; |
233 if (r == Z_DATA_ERROR) { | 233 break; |
234 z.istate.mode = BAD; | 234 } |
235 z.istate.marker = 0; // can try inflateSync | 235 |
236 break; | 236 flags = 0; |
237 } | 237 |
238 | 238 this.method = ((int)this.need)&0xff; |
239 if (r == Z_OK) { | 239 b=((int)(this.need>>8))&0xff; |
240 r = f; | 240 |
241 } | 241 if(((wrap&1)==0 || // check if zlib header allowed |
242 | 242 (((this.method << 8)+b) % 31)!=0) && |
243 if (r != Z_STREAM_END) { | 243 (this.method&0xf)!=Z_DEFLATED){ |
244 return r; | 244 if(wrap == 4){ |
245 } | 245 z.next_in_index -= 2; |
246 | 246 z.avail_in += 2; |
247 r = f; | 247 z.total_in -= 2; |
248 z.istate.blocks.reset(z, z.istate.was); | 248 wrap = 0; |
249 | 249 this.mode = BLOCKS; |
250 if (z.istate.nowrap != 0) { | 250 break; |
251 z.istate.mode = DONE; | 251 } |
252 break; | 252 this.mode = BAD; |
253 } | 253 z.msg = "incorrect header check"; |
254 | 254 // since zlib 1.2, it is allowted to inflateSync for this case. |
255 z.istate.mode = CHECK4; | 255 /* |
256 | 256 this.marker = 5; // can't try inflateSync |
257 case CHECK4: | 257 */ |
258 if (z.avail_in == 0)return r; r = f; | 258 break; |
259 | 259 } |
260 z.avail_in--; z.total_in++; | 260 |
261 z.istate.need = ((z.next_in[z.next_in_index++] & 0xff) << 24) & 0xff000000L; | 261 if((this.method&0xf)!=Z_DEFLATED){ |
262 z.istate.mode = CHECK3; | 262 this.mode = BAD; |
263 | 263 z.msg="unknown compression method"; |
264 case CHECK3: | 264 // since zlib 1.2, it is allowted to inflateSync for this case. |
265 if (z.avail_in == 0)return r; r = f; | 265 /* |
266 | 266 this.marker = 5; // can't try inflateSync |
267 z.avail_in--; z.total_in++; | 267 */ |
268 z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 16) & 0xff0000L; | 268 break; |
269 z.istate.mode = CHECK2; | 269 } |
270 | 270 |
271 case CHECK2: | 271 if(wrap == 4){ |
272 if (z.avail_in == 0)return r; r = f; | 272 wrap = 1; |
273 | 273 } |
274 z.avail_in--; z.total_in++; | 274 |
275 z.istate.need += ((z.next_in[z.next_in_index++] & 0xff) << 8) & 0xff00L; | 275 if((this.method>>4)+8>this.wbits){ |
276 z.istate.mode = CHECK1; | 276 this.mode = BAD; |
277 | 277 z.msg="invalid window size"; |
278 case CHECK1: | 278 // since zlib 1.2, it is allowted to inflateSync for this case. |
279 if (z.avail_in == 0)return r; r = f; | 279 /* |
280 | 280 this.marker = 5; // can't try inflateSync |
281 z.avail_in--; z.total_in++; | 281 */ |
282 z.istate.need += (z.next_in[z.next_in_index++] & 0xffL); | 282 break; |
283 | 283 } |
284 if (((int)(z.istate.was[0])) != ((int)(z.istate.need))) { | 284 |
285 z.istate.mode = BAD; | 285 z.adler=new Adler32(); |
286 z.msg = "incorrect data check"; | 286 |
287 z.istate.marker = 5; // can't try inflateSync | 287 if((b&PRESET_DICT)==0){ |
288 break; | 288 this.mode = BLOCKS; |
289 } | 289 break; |
290 | 290 } |
291 z.istate.mode = DONE; | 291 this.mode = DICT4; |
292 | 292 case DICT4: |
293 case DONE: | 293 |
294 return Z_STREAM_END; | 294 if(z.avail_in==0)return r;r=f; |
295 | 295 |
296 case BAD: | 296 z.avail_in--; z.total_in++; |
297 return Z_DATA_ERROR; | 297 this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; |
298 | 298 this.mode=DICT3; |
299 default: | 299 case DICT3: |
300 return Z_STREAM_ERROR; | 300 |
301 if(z.avail_in==0)return r;r=f; | |
302 | |
303 z.avail_in--; z.total_in++; | |
304 this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; | |
305 this.mode=DICT2; | |
306 case DICT2: | |
307 | |
308 if(z.avail_in==0)return r;r=f; | |
309 | |
310 z.avail_in--; z.total_in++; | |
311 this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; | |
312 this.mode=DICT1; | |
313 case DICT1: | |
314 | |
315 if(z.avail_in==0)return r;r=f; | |
316 | |
317 z.avail_in--; z.total_in++; | |
318 this.need += (z.next_in[z.next_in_index++]&0xffL); | |
319 z.adler.reset(this.need); | |
320 this.mode = DICT0; | |
321 return Z_NEED_DICT; | |
322 case DICT0: | |
323 this.mode = BAD; | |
324 z.msg = "need dictionary"; | |
325 this.marker = 0; // can try inflateSync | |
326 return Z_STREAM_ERROR; | |
327 case BLOCKS: | |
328 r = this.blocks.proc(r); | |
329 if(r == Z_DATA_ERROR){ | |
330 this.mode = BAD; | |
331 this.marker = 0; // can try inflateSync | |
332 break; | |
333 } | |
334 if(r == Z_OK){ | |
335 r = f; | |
336 } | |
337 if(r != Z_STREAM_END){ | |
338 return r; | |
339 } | |
340 r = f; | |
341 this.was=z.adler.getValue(); | |
342 this.blocks.reset(); | |
343 if(this.wrap==0){ | |
344 this.mode=DONE; | |
345 break; | |
346 } | |
347 this.mode=CHECK4; | |
348 case CHECK4: | |
349 | |
350 if(z.avail_in==0)return r;r=f; | |
351 | |
352 z.avail_in--; z.total_in++; | |
353 this.need=((z.next_in[z.next_in_index++]&0xff)<<24)&0xff000000L; | |
354 this.mode=CHECK3; | |
355 case CHECK3: | |
356 | |
357 if(z.avail_in==0)return r;r=f; | |
358 | |
359 z.avail_in--; z.total_in++; | |
360 this.need+=((z.next_in[z.next_in_index++]&0xff)<<16)&0xff0000L; | |
361 this.mode = CHECK2; | |
362 case CHECK2: | |
363 | |
364 if(z.avail_in==0)return r;r=f; | |
365 | |
366 z.avail_in--; z.total_in++; | |
367 this.need+=((z.next_in[z.next_in_index++]&0xff)<<8)&0xff00L; | |
368 this.mode = CHECK1; | |
369 case CHECK1: | |
370 | |
371 if(z.avail_in==0)return r;r=f; | |
372 | |
373 z.avail_in--; z.total_in++; | |
374 this.need+=(z.next_in[z.next_in_index++]&0xffL); | |
375 | |
376 if(flags!=0){ // gzip | |
377 this.need = ((this.need&0xff000000)>>24 | | |
378 (this.need&0x00ff0000)>>8 | | |
379 (this.need&0x0000ff00)<<8 | | |
380 (this.need&0x0000ffff)<<24)&0xffffffffL; | |
381 } | |
382 | |
383 if(((int)(this.was)) != ((int)(this.need))){ | |
384 z.msg = "incorrect data check"; | |
385 // chack is delayed | |
386 /* | |
387 this.mode = BAD; | |
388 this.marker = 5; // can't try inflateSync | |
389 break; | |
390 */ | |
391 } | |
392 else if(flags!=0 && gheader!=null){ | |
393 gheader.crc = this.need; | |
394 } | |
395 | |
396 this.mode = LENGTH; | |
397 case LENGTH: | |
398 if (wrap!=0 && flags!=0) { | |
399 | |
400 try { r=readBytes(4, r, f); } | |
401 catch(Return e){ return e.r; } | |
402 | |
403 if(z.msg!=null && z.msg.equals("incorrect data check")){ | |
404 this.mode = BAD; | |
405 this.marker = 5; // can't try inflateSync | |
406 break; | |
407 } | |
408 | |
409 if (this.need != (z.total_out & 0xffffffffL)) { | |
410 z.msg = "incorrect length check"; | |
411 this.mode = BAD; | |
412 break; | |
413 } | |
414 z.msg = null; | |
415 } | |
416 else { | |
417 if(z.msg!=null && z.msg.equals("incorrect data check")){ | |
418 this.mode = BAD; | |
419 this.marker = 5; // can't try inflateSync | |
420 break; | |
421 } | |
422 } | |
423 | |
424 this.mode = DONE; | |
425 case DONE: | |
426 return Z_STREAM_END; | |
427 case BAD: | |
428 return Z_DATA_ERROR; | |
429 | |
430 case FLAGS: | |
431 | |
432 try { r=readBytes(2, r, f); } | |
433 catch(Return e){ return e.r; } | |
434 | |
435 flags = ((int)this.need)&0xffff; | |
436 | |
437 if ((flags & 0xff) != Z_DEFLATED) { | |
438 z.msg = "unknown compression method"; | |
439 this.mode = BAD; | |
440 break; | |
441 } | |
442 if ((flags & 0xe000)!=0) { | |
443 z.msg = "unknown header flags set"; | |
444 this.mode = BAD; | |
445 break; | |
446 } | |
447 | |
448 if ((flags & 0x0200)!=0){ | |
449 checksum(2, this.need); | |
450 } | |
451 | |
452 this.mode = TIME; | |
453 | |
454 case TIME: | |
455 try { r=readBytes(4, r, f); } | |
456 catch(Return e){ return e.r; } | |
457 if(gheader!=null) | |
458 gheader.time = this.need; | |
459 if ((flags & 0x0200)!=0){ | |
460 checksum(4, this.need); | |
461 } | |
462 this.mode = OS; | |
463 case OS: | |
464 try { r=readBytes(2, r, f); } | |
465 catch(Return e){ return e.r; } | |
466 if(gheader!=null){ | |
467 gheader.xflags = ((int)this.need)&0xff; | |
468 gheader.os = (((int)this.need)>>8)&0xff; | |
469 } | |
470 if ((flags & 0x0200)!=0){ | |
471 checksum(2, this.need); | |
472 } | |
473 this.mode = EXLEN; | |
474 case EXLEN: | |
475 if ((flags & 0x0400)!=0) { | |
476 try { r=readBytes(2, r, f); } | |
477 catch(Return e){ return e.r; } | |
478 if(gheader!=null){ | |
479 gheader.extra = new byte[((int)this.need)&0xffff]; | |
480 } | |
481 if ((flags & 0x0200)!=0){ | |
482 checksum(2, this.need); | |
483 } | |
484 } | |
485 else if(gheader!=null){ | |
486 gheader.extra=null; | |
487 } | |
488 this.mode = EXTRA; | |
489 | |
490 case EXTRA: | |
491 if ((flags & 0x0400)!=0) { | |
492 try { | |
493 r=readBytes(r, f); | |
494 if(gheader!=null){ | |
495 byte[] foo = tmp_string.toByteArray(); | |
496 tmp_string=null; | |
497 if(foo.length == gheader.extra.length){ | |
498 System.arraycopy(foo, 0, gheader.extra, 0, foo.length); | |
499 } | |
500 else{ | |
501 z.msg = "bad extra field length"; | |
502 this.mode = BAD; | |
503 break; | |
504 } | |
301 } | 505 } |
302 } | 506 } |
303 } | 507 catch(Return e){ return e.r; } |
304 | 508 } |
305 | 509 else if(gheader!=null){ |
306 int inflateSetDictionary(ZStream z, byte[] dictionary, int dictLength) { | 510 gheader.extra=null; |
307 int index = 0; | 511 } |
308 int length = dictLength; | 512 this.mode = NAME; |
309 | 513 case NAME: |
310 if (z == null || z.istate == null || z.istate.mode != DICT0) | 514 if ((flags & 0x0800)!=0) { |
311 return Z_STREAM_ERROR; | 515 try { |
312 | 516 r=readString(r, f); |
313 if (z._adler.adler32(1L, dictionary, 0, dictLength) != z.adler) { | 517 if(gheader!=null){ |
314 return Z_DATA_ERROR; | 518 gheader.name=tmp_string.toByteArray(); |
315 } | |
316 | |
317 z.adler = z._adler.adler32(0, null, 0, 0); | |
318 | |
319 if (length >= (1 << z.istate.wbits)) { | |
320 length = (1 << z.istate.wbits) - 1; | |
321 index = dictLength - length; | |
322 } | |
323 | |
324 z.istate.blocks.set_dictionary(dictionary, index, length); | |
325 z.istate.mode = BLOCKS; | |
326 return Z_OK; | |
327 } | |
328 | |
329 static private byte[] mark = { (byte)0, (byte)0, (byte)0xff, (byte)0xff}; | |
330 | |
331 int inflateSync(ZStream z) { | |
332 int n; // number of bytes to look at | |
333 int p; // pointer to bytes | |
334 int m; // number of marker bytes found in a row | |
335 long r, w; // temporaries to save total_in and total_out | |
336 | |
337 // set up | |
338 if (z == null || z.istate == null) | |
339 return Z_STREAM_ERROR; | |
340 | |
341 if (z.istate.mode != BAD) { | |
342 z.istate.mode = BAD; | |
343 z.istate.marker = 0; | |
344 } | |
345 | |
346 if ((n = z.avail_in) == 0) | |
347 return Z_BUF_ERROR; | |
348 | |
349 p = z.next_in_index; | |
350 m = z.istate.marker; | |
351 | |
352 // search | |
353 while (n != 0 && m < 4) { | |
354 if (z.next_in[p] == mark[m]) { | |
355 m++; | |
356 } | 519 } |
357 else if (z.next_in[p] != 0) { | 520 tmp_string=null; |
358 m = 0; | 521 } |
522 catch(Return e){ return e.r; } | |
523 } | |
524 else if(gheader!=null){ | |
525 gheader.name=null; | |
526 } | |
527 this.mode = COMMENT; | |
528 case COMMENT: | |
529 if ((flags & 0x1000)!=0) { | |
530 try { | |
531 r=readString(r, f); | |
532 if(gheader!=null){ | |
533 gheader.comment=tmp_string.toByteArray(); | |
359 } | 534 } |
360 else { | 535 tmp_string=null; |
361 m = 4 - m; | 536 } |
362 } | 537 catch(Return e){ return e.r; } |
363 | 538 } |
364 p++; n--; | 539 else if(gheader!=null){ |
365 } | 540 gheader.comment=null; |
366 | 541 } |
367 // restore | 542 this.mode = HCRC; |
368 z.total_in += p - z.next_in_index; | 543 case HCRC: |
369 z.next_in_index = p; | 544 if ((flags & 0x0200)!=0) { |
370 z.avail_in = n; | 545 try { r=readBytes(2, r, f); } |
371 z.istate.marker = m; | 546 catch(Return e){ return e.r; } |
372 | 547 if(gheader!=null){ |
373 // return no joy or set up to restart on a new block | 548 gheader.hcrc=(int)(this.need&0xffff); |
374 if (m != 4) { | 549 } |
375 return Z_DATA_ERROR; | 550 if(this.need != (z.adler.getValue()&0xffffL)){ |
376 } | 551 this.mode = BAD; |
377 | 552 z.msg = "header crc mismatch"; |
378 r = z.total_in; w = z.total_out; | 553 this.marker = 5; // can't try inflateSync |
379 inflateReset(z); | 554 break; |
380 z.total_in = r; z.total_out = w; | 555 } |
381 z.istate.mode = BLOCKS; | 556 } |
382 return Z_OK; | 557 z.adler = new CRC32(); |
383 } | 558 |
384 | 559 this.mode = BLOCKS; |
385 // Returns true if inflate is currently at the end of a block generated | 560 break; |
386 // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP | 561 default: |
387 // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH | 562 return Z_STREAM_ERROR; |
388 // but removes the length bytes of the resulting empty stored block. When | 563 } |
389 // decompressing, PPP checks that at the end of input packet, inflate is | 564 } |
390 // waiting for these length bytes. | 565 } |
391 int inflateSyncPoint(ZStream z) { | 566 |
392 if (z == null || z.istate == null || z.istate.blocks == null) | 567 int inflateSetDictionary(byte[] dictionary, int dictLength){ |
393 return Z_STREAM_ERROR; | 568 if(z==null || (this.mode != DICT0 && this.wrap != 0)){ |
394 | 569 return Z_STREAM_ERROR; |
395 return z.istate.blocks.sync_point(); | 570 } |
396 } | 571 |
572 int index=0; | |
573 int length = dictLength; | |
574 | |
575 if(this.mode==DICT0){ | |
576 long adler_need=z.adler.getValue(); | |
577 z.adler.reset(); | |
578 z.adler.update(dictionary, 0, dictLength); | |
579 if(z.adler.getValue()!=adler_need){ | |
580 return Z_DATA_ERROR; | |
581 } | |
582 } | |
583 | |
584 z.adler.reset(); | |
585 | |
586 if(length >= (1<<this.wbits)){ | |
587 length = (1<<this.wbits)-1; | |
588 index=dictLength - length; | |
589 } | |
590 this.blocks.set_dictionary(dictionary, index, length); | |
591 this.mode = BLOCKS; | |
592 return Z_OK; | |
593 } | |
594 | |
595 static private byte[] mark = {(byte)0, (byte)0, (byte)0xff, (byte)0xff}; | |
596 | |
597 int inflateSync(){ | |
598 int n; // number of bytes to look at | |
599 int p; // pointer to bytes | |
600 int m; // number of marker bytes found in a row | |
601 long r, w; // temporaries to save total_in and total_out | |
602 | |
603 // set up | |
604 if(z == null) | |
605 return Z_STREAM_ERROR; | |
606 if(this.mode != BAD){ | |
607 this.mode = BAD; | |
608 this.marker = 0; | |
609 } | |
610 if((n=z.avail_in)==0) | |
611 return Z_BUF_ERROR; | |
612 | |
613 p=z.next_in_index; | |
614 m=this.marker; | |
615 // search | |
616 while (n!=0 && m < 4){ | |
617 if(z.next_in[p] == mark[m]){ | |
618 m++; | |
619 } | |
620 else if(z.next_in[p]!=0){ | |
621 m = 0; | |
622 } | |
623 else{ | |
624 m = 4 - m; | |
625 } | |
626 p++; n--; | |
627 } | |
628 | |
629 // restore | |
630 z.total_in += p-z.next_in_index; | |
631 z.next_in_index = p; | |
632 z.avail_in = n; | |
633 this.marker = m; | |
634 | |
635 // return no joy or set up to restart on a new block | |
636 if(m != 4){ | |
637 return Z_DATA_ERROR; | |
638 } | |
639 r=z.total_in; w=z.total_out; | |
640 inflateReset(); | |
641 z.total_in=r; z.total_out = w; | |
642 this.mode = BLOCKS; | |
643 | |
644 return Z_OK; | |
645 } | |
646 | |
647 // Returns true if inflate is currently at the end of a block generated | |
648 // by Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP | |
649 // implementation to provide an additional safety check. PPP uses Z_SYNC_FLUSH | |
650 // but removes the length bytes of the resulting empty stored block. When | |
651 // decompressing, PPP checks that at the end of input packet, inflate is | |
652 // waiting for these length bytes. | |
653 int inflateSyncPoint(){ | |
654 if(z == null || this.blocks == null) | |
655 return Z_STREAM_ERROR; | |
656 return this.blocks.sync_point(); | |
657 } | |
658 | |
659 private int readBytes(int n, int r, int f) throws Return{ | |
660 if(need_bytes == -1){ | |
661 need_bytes=n; | |
662 this.need=0; | |
663 } | |
664 while(need_bytes>0){ | |
665 if(z.avail_in==0){ throw new Return(r); }; r=f; | |
666 z.avail_in--; z.total_in++; | |
667 this.need = this.need | | |
668 ((z.next_in[z.next_in_index++]&0xff)<<((n-need_bytes)*8)); | |
669 need_bytes--; | |
670 } | |
671 if(n==2){ | |
672 this.need&=0xffffL; | |
673 } | |
674 else if(n==4) { | |
675 this.need&=0xffffffffL; | |
676 } | |
677 need_bytes=-1; | |
678 return r; | |
679 } | |
680 class Return extends Exception{ | |
681 int r; | |
682 Return(int r){this.r=r; } | |
683 } | |
684 | |
685 private java.io.ByteArrayOutputStream tmp_string = null; | |
686 private int readString(int r, int f) throws Return{ | |
687 if(tmp_string == null){ | |
688 tmp_string=new java.io.ByteArrayOutputStream(); | |
689 } | |
690 int b=0; | |
691 do { | |
692 if(z.avail_in==0){ throw new Return(r); }; r=f; | |
693 z.avail_in--; z.total_in++; | |
694 b = z.next_in[z.next_in_index]; | |
695 if(b!=0) tmp_string.write(z.next_in, z.next_in_index, 1); | |
696 z.adler.update(z.next_in, z.next_in_index, 1); | |
697 z.next_in_index++; | |
698 }while(b!=0); | |
699 return r; | |
700 } | |
701 | |
702 private int readBytes(int r, int f) throws Return{ | |
703 if(tmp_string == null){ | |
704 tmp_string=new java.io.ByteArrayOutputStream(); | |
705 } | |
706 int b=0; | |
707 while(this.need>0){ | |
708 if(z.avail_in==0){ throw new Return(r); }; r=f; | |
709 z.avail_in--; z.total_in++; | |
710 b = z.next_in[z.next_in_index]; | |
711 tmp_string.write(z.next_in, z.next_in_index, 1); | |
712 z.adler.update(z.next_in, z.next_in_index, 1); | |
713 z.next_in_index++; | |
714 this.need--; | |
715 } | |
716 return r; | |
717 } | |
718 | |
719 private void checksum(int n, long v){ | |
720 for(int i=0; i<n; i++){ | |
721 crcbuf[i]=(byte)(v&0xff); | |
722 v>>=8; | |
723 } | |
724 z.adler.update(crcbuf, 0, n); | |
725 } | |
726 | |
727 public GZIPHeader getGZIPHeader(){ | |
728 return gheader; | |
729 } | |
730 | |
731 boolean inParsingHeader(){ | |
732 switch(mode){ | |
733 case HEAD: | |
734 case DICT4: | |
735 case DICT3: | |
736 case DICT2: | |
737 case DICT1: | |
738 case FLAGS: | |
739 case TIME: | |
740 case OS: | |
741 case EXLEN: | |
742 case EXTRA: | |
743 case NAME: | |
744 case COMMENT: | |
745 case HCRC: | |
746 return true; | |
747 default: | |
748 return false; | |
749 } | |
750 } | |
397 } | 751 } |