/src/gdal/frmts/zlib/contrib/infback9/infback9.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* infback9.c -- inflate deflate64 data using a call-back interface |
2 | | * Copyright (C) 1995-2008 Mark Adler |
3 | | * For conditions of distribution and use, see copyright notice in zlib.h |
4 | | */ |
5 | | |
6 | | #include "minified_zutil.h" |
7 | | #include "infback9.h" |
8 | | #include "inftree9.h" |
9 | | #include "inflate9.h" |
10 | | #include <assert.h> |
11 | | #include <string.h> |
12 | | |
13 | | #undef ZEXPORT |
14 | | #define ZEXPORT |
15 | | |
16 | 0 | #define WSIZE 65536UL |
17 | | |
18 | | /* |
19 | | strm provides memory allocation functions in zalloc and zfree, or |
20 | | Z_NULL to use the library memory allocation functions. |
21 | | |
22 | | window is a user-supplied window and output buffer that is 64K bytes. |
23 | | */ |
24 | | int ZEXPORT inflateBack9Init_(z_stream FAR *strm, |
25 | | unsigned char FAR *window, |
26 | | const char *version, |
27 | | int stream_size) |
28 | 0 | { |
29 | 0 | struct inflate_state FAR *state; |
30 | |
|
31 | 0 | if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || |
32 | 0 | stream_size != (int)(sizeof(z_stream))) |
33 | 0 | return Z_VERSION_ERROR; |
34 | 0 | if (strm == Z_NULL /* || window == Z_NULL*/) |
35 | 0 | return Z_STREAM_ERROR; |
36 | 0 | strm->msg = Z_NULL; /* in case we return an error */ |
37 | 0 | if (strm->zalloc == (alloc_func)0) { |
38 | 0 | strm->zalloc = zcalloc; |
39 | 0 | strm->opaque = (voidpf)0; |
40 | 0 | } |
41 | 0 | if (strm->zfree == (free_func)0) strm->zfree = zcfree; |
42 | 0 | state = (struct inflate_state FAR *)ZALLOC(strm, 1, |
43 | 0 | sizeof(struct inflate_state)); |
44 | 0 | if (state == Z_NULL) return Z_MEM_ERROR; |
45 | 0 | memset(state, 0, sizeof(struct inflate_state)); |
46 | 0 | Tracev((stderr, "inflate: allocated\n")); |
47 | 0 | strm->state = (voidpf)state; |
48 | | |
49 | | // Added by E. Rouault |
50 | 0 | if( window == Z_NULL ) |
51 | 0 | { |
52 | 0 | window = (unsigned char FAR *) |
53 | 0 | ZALLOC(strm, WSIZE, |
54 | 0 | sizeof(unsigned char)); |
55 | 0 | if (window == Z_NULL) return Z_MEM_ERROR; |
56 | 0 | } |
57 | | |
58 | 0 | state->window = window; |
59 | 0 | state->mode = TYPE; |
60 | 0 | state->left = WSIZE; |
61 | 0 | return Z_OK; |
62 | 0 | } |
63 | | |
64 | | /* |
65 | | Build and output length and distance decoding tables for fixed code |
66 | | decoding. |
67 | | */ |
68 | | #ifdef MAKEFIXED |
69 | | #include <stdio.h> |
70 | | |
71 | | void makefixed9(void) |
72 | | { |
73 | | unsigned sym, bits, low, size; |
74 | | code *next, *lenfix, *distfix; |
75 | | struct inflate_state state; |
76 | | code fixed[544]; |
77 | | |
78 | | /* literal/length table */ |
79 | | sym = 0; |
80 | | while (sym < 144) state.lens[sym++] = 8; |
81 | | while (sym < 256) state.lens[sym++] = 9; |
82 | | while (sym < 280) state.lens[sym++] = 7; |
83 | | while (sym < 288) state.lens[sym++] = 8; |
84 | | next = fixed; |
85 | | lenfix = next; |
86 | | bits = 9; |
87 | | inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work); |
88 | | |
89 | | /* distance table */ |
90 | | sym = 0; |
91 | | while (sym < 32) state.lens[sym++] = 5; |
92 | | distfix = next; |
93 | | bits = 5; |
94 | | inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work); |
95 | | |
96 | | /* write tables */ |
97 | | puts(" /* inffix9.h -- table for decoding deflate64 fixed codes"); |
98 | | puts(" * Generated automatically by makefixed9()."); |
99 | | puts(" */"); |
100 | | puts(""); |
101 | | puts(" /* WARNING: this file should *not* be used by applications."); |
102 | | puts(" It is part of the implementation of this library and is"); |
103 | | puts(" subject to change. Applications should only use zlib.h."); |
104 | | puts(" */"); |
105 | | puts(""); |
106 | | size = 1U << 9; |
107 | | printf(" static const code lenfix[%u] = {", size); |
108 | | low = 0; |
109 | | for (;;) { |
110 | | if ((low % 6) == 0) printf("\n "); |
111 | | printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits, |
112 | | lenfix[low].val); |
113 | | if (++low == size) break; |
114 | | putchar(','); |
115 | | } |
116 | | puts("\n };"); |
117 | | size = 1U << 5; |
118 | | printf("\n static const code distfix[%u] = {", size); |
119 | | low = 0; |
120 | | for (;;) { |
121 | | if ((low % 5) == 0) printf("\n "); |
122 | | printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits, |
123 | | distfix[low].val); |
124 | | if (++low == size) break; |
125 | | putchar(','); |
126 | | } |
127 | | puts("\n };"); |
128 | | } |
129 | | #endif /* MAKEFIXED */ |
130 | | |
131 | | /* Macros for inflateBack(): */ |
132 | | |
133 | | /* Clear the input bit accumulator */ |
134 | | #define INITBITS() \ |
135 | 0 | do { \ |
136 | 0 | hold = 0; \ |
137 | 0 | bits = 0; \ |
138 | 0 | } while (0) |
139 | | |
140 | | /* Assure that some input is available. If input is requested, but denied, |
141 | | then return a Z_BUF_ERROR from inflateBack(). */ |
142 | | #define PULL() \ |
143 | 0 | do { \ |
144 | 0 | if (have == 0) { \ |
145 | 0 | have = in(in_desc, &next); \ |
146 | 0 | if (have == 0) { \ |
147 | 0 | next = Z_NULL; \ |
148 | 0 | ret = Z_BUF_ERROR; \ |
149 | 0 | goto inf_leave; \ |
150 | 0 | } \ |
151 | 0 | } \ |
152 | 0 | } while (0) |
153 | | |
154 | | /* Get a byte of input into the bit accumulator, or return from inflateBack() |
155 | | with an error if there is no input available. */ |
156 | | #define PULLBYTE() \ |
157 | 0 | do { \ |
158 | 0 | PULL(); \ |
159 | 0 | have--; \ |
160 | 0 | hold += (unsigned long)(*next++) << bits; \ |
161 | 0 | bits += 8; \ |
162 | 0 | } while (0) |
163 | | |
164 | | /* Assure that there are at least n bits in the bit accumulator. If there is |
165 | | not enough available input to do that, then return from inflateBack() with |
166 | | an error. */ |
167 | | #define NEEDBITS(n) \ |
168 | 0 | do { \ |
169 | 0 | while (bits < (unsigned)(n)) \ |
170 | 0 | PULLBYTE(); \ |
171 | 0 | } while (0) |
172 | | |
173 | | /* Return the low n bits of the bit accumulator (n <= 16) */ |
174 | | #define BITS(n) \ |
175 | 0 | ((unsigned)hold & ((1U << (n)) - 1)) |
176 | | |
177 | | /* Remove n bits from the bit accumulator */ |
178 | | #define DROPBITS(n) \ |
179 | 0 | do { \ |
180 | 0 | hold >>= (n); \ |
181 | 0 | bits -= (unsigned)(n); \ |
182 | 0 | } while (0) |
183 | | |
184 | | /* Remove zero to seven bits as needed to go to a byte boundary */ |
185 | | #define BYTEBITS() \ |
186 | 0 | do { \ |
187 | 0 | hold >>= bits & 7; \ |
188 | 0 | bits -= bits & 7; \ |
189 | 0 | } while (0) |
190 | | |
191 | | /* Assure that some output space is available, by writing out the window |
192 | | if it's full. If the write fails, return from inflateBack() with a |
193 | | Z_BUF_ERROR. */ |
194 | | #define ROOM() \ |
195 | 0 | do { \ |
196 | 0 | if (left == 0) { \ |
197 | 0 | put = window; \ |
198 | 0 | left = WSIZE; \ |
199 | 0 | wrap = 1; \ |
200 | 0 | if (out(out_desc, put, (unsigned)left)) { \ |
201 | 0 | ret = Z_BUF_ERROR; \ |
202 | 0 | goto inf_leave; \ |
203 | 0 | } \ |
204 | 0 | } \ |
205 | 0 | } while (0) |
206 | | |
207 | | /* |
208 | | strm provides the memory allocation functions and window buffer on input, |
209 | | and provides information on the unused input on return. For Z_DATA_ERROR |
210 | | returns, strm will also provide an error message. |
211 | | |
212 | | in() and out() are the call-back input and output functions. When |
213 | | inflateBack() needs more input, it calls in(). When inflateBack() has |
214 | | filled the window with output, or when it completes with data in the |
215 | | window, it calls out() to write out the data. The application must not |
216 | | change the provided input until in() is called again or inflateBack() |
217 | | returns. The application must not change the window/output buffer until |
218 | | inflateBack() returns. |
219 | | |
220 | | in() and out() are called with a descriptor parameter provided in the |
221 | | inflateBack() call. This parameter can be a structure that provides the |
222 | | information required to do the read or write, as well as accumulated |
223 | | information on the input and output such as totals and check values. |
224 | | |
225 | | in() should return zero on failure. out() should return non-zero on |
226 | | failure. If either in() or out() fails, than inflateBack() returns a |
227 | | Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it |
228 | | was in() or out() that caused in the error. Otherwise, inflateBack() |
229 | | returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format |
230 | | error, or Z_MEM_ERROR if it could not allocate memory for the state. |
231 | | inflateBack() can also return Z_STREAM_ERROR if the input parameters |
232 | | are not correct, i.e. strm is Z_NULL or the state was not initialized. |
233 | | */ |
234 | | int ZEXPORT inflateBack9(z_stream FAR *strm, in_func in, void FAR *in_desc, out_func out, void FAR *out_desc) |
235 | 0 | { |
236 | 0 | struct inflate_state FAR *state; |
237 | 0 | z_const unsigned char FAR *next; /* next input */ |
238 | 0 | unsigned char FAR *put; /* next output */ |
239 | 0 | unsigned have; /* available input */ |
240 | 0 | unsigned long left; /* available output */ |
241 | 0 | inflate_mode mode; /* current inflate mode */ |
242 | 0 | int lastblock; /* true if processing last block */ |
243 | 0 | int wrap; /* true if the window has wrapped */ |
244 | 0 | unsigned char FAR *window; /* allocated sliding window, if needed */ |
245 | 0 | unsigned long hold; /* bit buffer */ |
246 | 0 | unsigned bits; /* bits in bit buffer */ |
247 | 0 | unsigned extra; /* extra bits needed */ |
248 | 0 | unsigned long length; /* literal or length of data to copy */ |
249 | 0 | unsigned long offset; /* distance back to copy string from */ |
250 | 0 | unsigned long copy; /* number of stored or match bytes to copy */ |
251 | 0 | unsigned char FAR *from; /* where to copy match bytes from */ |
252 | 0 | code const FAR *lencode; /* starting table for length/literal codes */ |
253 | 0 | code const FAR *distcode; /* starting table for distance codes */ |
254 | 0 | unsigned lenbits; /* index bits for lencode */ |
255 | 0 | unsigned distbits; /* index bits for distcode */ |
256 | 0 | code here; /* current decoding table entry */ |
257 | 0 | code last; /* parent table entry */ |
258 | 0 | unsigned len; /* length to copy for repeats, bits to drop */ |
259 | 0 | int ret; /* return code */ |
260 | 0 | static const unsigned short order[19] = /* permutation of code lengths */ |
261 | 0 | {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; |
262 | 0 | #include "inffix9.h" |
263 | | |
264 | | /* Check that the strm exists and that the state was initialized */ |
265 | 0 | if (strm == Z_NULL || strm->state == Z_NULL) |
266 | 0 | return Z_STREAM_ERROR; |
267 | 0 | state = (struct inflate_state FAR *)strm->state; |
268 | | |
269 | | /* Reset the state */ |
270 | 0 | strm->msg = Z_NULL; |
271 | | //mode = TYPE; |
272 | | //lastblock = 0; |
273 | | //wrap = 0; |
274 | 0 | window = state->window; |
275 | 0 | next = strm->next_in; |
276 | 0 | have = next != Z_NULL ? strm->avail_in : 0; |
277 | | //hold = 0; |
278 | | //bits = 0; |
279 | 0 | left = state->left; |
280 | 0 | put = window + (unsigned)(WSIZE - state->left); |
281 | | //lencode = Z_NULL; |
282 | | //distcode = Z_NULL; |
283 | |
|
284 | 0 | mode = state->mode; |
285 | 0 | wrap = state->wrap; // wrap meaning is different from inflate.c |
286 | 0 | hold = state->hold; |
287 | 0 | bits = state->bits; |
288 | 0 | extra = state->extra; |
289 | 0 | length = state->length; |
290 | 0 | offset = state->offset; |
291 | 0 | lencode = state->lencode; |
292 | 0 | distcode = state->distcode; |
293 | 0 | lenbits = state->lenbits; |
294 | 0 | distbits = state->distbits; |
295 | 0 | lastblock = state->last; |
296 | | |
297 | | /* Inflate until end of block marked as last */ |
298 | 0 | for (;;) |
299 | 0 | switch (mode) { |
300 | 0 | case TYPE: |
301 | | /* determine and dispatch block type */ |
302 | 0 | if (lastblock) { |
303 | 0 | BYTEBITS(); |
304 | 0 | mode = DONE; |
305 | 0 | break; |
306 | 0 | } |
307 | 0 | NEEDBITS(3); |
308 | 0 | lastblock = BITS(1); |
309 | 0 | DROPBITS(1); |
310 | 0 | switch (BITS(2)) { |
311 | 0 | case 0: /* stored block */ |
312 | 0 | Tracev((stderr, "inflate: stored block%s\n", |
313 | 0 | lastblock ? " (last)" : "")); |
314 | 0 | mode = STORED; |
315 | 0 | break; |
316 | 0 | case 1: /* fixed block */ |
317 | 0 | lencode = lenfix; |
318 | 0 | lenbits = 9; |
319 | 0 | distcode = distfix; |
320 | 0 | distbits = 5; |
321 | 0 | Tracev((stderr, "inflate: fixed codes block%s\n", |
322 | 0 | lastblock ? " (last)" : "")); |
323 | 0 | mode = LEN; /* decode codes */ |
324 | 0 | break; |
325 | 0 | case 2: /* dynamic block */ |
326 | 0 | Tracev((stderr, "inflate: dynamic codes block%s\n", |
327 | 0 | lastblock ? " (last)" : "")); |
328 | 0 | mode = TABLE; |
329 | 0 | break; |
330 | 0 | case 3: |
331 | 0 | strm->msg = (char *)"invalid block type"; |
332 | 0 | mode = BAD; |
333 | 0 | } |
334 | 0 | DROPBITS(2); |
335 | 0 | break; |
336 | | |
337 | 0 | case STORED: |
338 | | /* get and verify stored block length */ |
339 | 0 | BYTEBITS(); /* go to byte boundary */ |
340 | 0 | NEEDBITS(32); |
341 | 0 | if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { |
342 | 0 | strm->msg = (char *)"invalid stored block lengths"; |
343 | 0 | mode = BAD; |
344 | 0 | break; |
345 | 0 | } |
346 | 0 | length = (unsigned)hold & 0xffff; |
347 | 0 | Tracev((stderr, "inflate: stored length %lu\n", |
348 | 0 | length)); |
349 | 0 | INITBITS(); |
350 | 0 | mode = COPY; |
351 | | //fallthrough |
352 | |
|
353 | 0 | case COPY: |
354 | | /* copy stored block from input to output */ |
355 | 0 | while (length != 0) { |
356 | 0 | copy = length; |
357 | 0 | PULL(); |
358 | 0 | ROOM(); |
359 | 0 | if (copy > have) copy = have; |
360 | 0 | if (copy > left) copy = left; |
361 | 0 | zmemcpy(put, next, (unsigned)copy); |
362 | 0 | have -= copy; |
363 | 0 | next += copy; |
364 | 0 | left -= copy; |
365 | 0 | put += copy; |
366 | 0 | length -= copy; |
367 | 0 | } |
368 | 0 | Tracev((stderr, "inflate: stored end\n")); |
369 | 0 | mode = TYPE; |
370 | 0 | break; |
371 | | |
372 | 0 | case TABLE: |
373 | | /* get dynamic table entries descriptor */ |
374 | 0 | NEEDBITS(14); |
375 | 0 | state->nlen = BITS(5) + 257; |
376 | 0 | DROPBITS(5); |
377 | 0 | state->ndist = BITS(5) + 1; |
378 | 0 | DROPBITS(5); |
379 | 0 | state->ncode = BITS(4) + 4; |
380 | 0 | DROPBITS(4); |
381 | 0 | if (state->nlen > 286) { |
382 | 0 | strm->msg = (char *)"too many length symbols"; |
383 | 0 | mode = BAD; |
384 | 0 | break; |
385 | 0 | } |
386 | 0 | Tracev((stderr, "inflate: table sizes ok\n")); |
387 | | |
388 | | /* get code length code lengths (not a typo) */ |
389 | 0 | state->have = 0; |
390 | 0 | mode = LENLENS; |
391 | | // fallthrough |
392 | |
|
393 | 0 | case LENLENS: |
394 | 0 | while (state->have < state->ncode) { |
395 | 0 | NEEDBITS(3); |
396 | 0 | state->lens[order[state->have++]] = (unsigned short)BITS(3); |
397 | 0 | DROPBITS(3); |
398 | 0 | } |
399 | 0 | while (state->have < 19) |
400 | 0 | state->lens[order[state->have++]] = 0; |
401 | 0 | state->next = state->codes; |
402 | 0 | lencode = (code const FAR *)(state->next); |
403 | 0 | lenbits = 7; |
404 | 0 | ret = inflate_table9(CODES, state->lens, 19, &(state->next), |
405 | 0 | &(lenbits), state->work); |
406 | 0 | if (ret) { |
407 | 0 | strm->msg = (char *)"invalid code lengths set"; |
408 | 0 | mode = BAD; |
409 | 0 | break; |
410 | 0 | } |
411 | 0 | Tracev((stderr, "inflate: code lengths ok\n")); |
412 | | |
413 | | /* get length and distance code code lengths */ |
414 | 0 | state->have = 0; |
415 | 0 | mode = CODELENS; |
416 | | // fallthrough |
417 | |
|
418 | 0 | case CODELENS: |
419 | 0 | while (state->have < state->nlen + state->ndist) { |
420 | 0 | for (;;) { |
421 | 0 | here = lencode[BITS(lenbits)]; |
422 | 0 | if ((unsigned)(here.bits) <= bits) break; |
423 | 0 | PULLBYTE(); |
424 | 0 | } |
425 | 0 | if (here.val < 16) { |
426 | 0 | NEEDBITS(here.bits); |
427 | 0 | DROPBITS(here.bits); |
428 | 0 | state->lens[state->have++] = here.val; |
429 | 0 | } |
430 | 0 | else { |
431 | 0 | if (here.val == 16) { |
432 | 0 | NEEDBITS(here.bits + 2); |
433 | 0 | DROPBITS(here.bits); |
434 | 0 | if (state->have == 0) { |
435 | 0 | strm->msg = (char *)"invalid bit length repeat"; |
436 | 0 | mode = BAD; |
437 | 0 | break; |
438 | 0 | } |
439 | 0 | len = (unsigned)(state->lens[state->have - 1]); |
440 | 0 | copy = 3 + BITS(2); |
441 | 0 | DROPBITS(2); |
442 | 0 | } |
443 | 0 | else if (here.val == 17) { |
444 | 0 | NEEDBITS(here.bits + 3); |
445 | 0 | DROPBITS(here.bits); |
446 | 0 | len = 0; |
447 | 0 | copy = 3 + BITS(3); |
448 | 0 | DROPBITS(3); |
449 | 0 | } |
450 | 0 | else { |
451 | 0 | NEEDBITS(here.bits + 7); |
452 | 0 | DROPBITS(here.bits); |
453 | 0 | len = 0; |
454 | 0 | copy = 11 + BITS(7); |
455 | 0 | DROPBITS(7); |
456 | 0 | } |
457 | 0 | if (state->have + copy > state->nlen + state->ndist) { |
458 | 0 | strm->msg = (char *)"invalid bit length repeat"; |
459 | 0 | mode = BAD; |
460 | 0 | break; |
461 | 0 | } |
462 | 0 | while (copy) |
463 | 0 | { |
464 | 0 | --copy; |
465 | 0 | state->lens[state->have++] = (unsigned short)len; |
466 | 0 | } |
467 | 0 | } |
468 | 0 | } |
469 | | |
470 | | /* handle error breaks in while */ |
471 | 0 | if (mode == BAD) break; |
472 | | |
473 | | /* check for end-of-block code (better have one) */ |
474 | 0 | if (state->lens[256] == 0) { |
475 | 0 | strm->msg = (char *)"invalid code -- missing end-of-block"; |
476 | 0 | mode = BAD; |
477 | 0 | break; |
478 | 0 | } |
479 | | |
480 | | /* build code tables -- note: do not change the lenbits or distbits |
481 | | values here (9 and 6) without reading the comments in inftree9.h |
482 | | concerning the ENOUGH constants, which depend on those values */ |
483 | 0 | state->next = state->codes; |
484 | 0 | lencode = (code const FAR *)(state->next); |
485 | 0 | lenbits = 9; |
486 | 0 | ret = inflate_table9(LENS, state->lens, state->nlen, |
487 | 0 | &(state->next), &(lenbits), state->work); |
488 | 0 | if (ret) { |
489 | 0 | strm->msg = (char *)"invalid literal/lengths set"; |
490 | 0 | mode = BAD; |
491 | 0 | break; |
492 | 0 | } |
493 | 0 | distcode = (code const FAR *)(state->next); |
494 | 0 | distbits = 6; |
495 | 0 | ret = inflate_table9(DISTS, state->lens + state->nlen, |
496 | 0 | state->ndist, &(state->next), &(distbits), |
497 | 0 | state->work); |
498 | 0 | if (ret) { |
499 | 0 | strm->msg = (char *)"invalid distances set"; |
500 | 0 | mode = BAD; |
501 | 0 | break; |
502 | 0 | } |
503 | 0 | Tracev((stderr, "inflate: codes ok\n")); |
504 | 0 | mode = LEN; |
505 | | // fallthrough |
506 | |
|
507 | 0 | case LEN: |
508 | | /* get a literal, length, or end-of-block code */ |
509 | 0 | for (;;) { |
510 | 0 | here = lencode[BITS(lenbits)]; |
511 | 0 | if ((unsigned)(here.bits) <= bits) break; |
512 | 0 | PULLBYTE(); |
513 | 0 | } |
514 | 0 | if (here.op && (here.op & 0xf0) == 0) { |
515 | 0 | last = here; |
516 | 0 | for (;;) { |
517 | 0 | here = lencode[last.val + |
518 | 0 | (BITS(last.bits + last.op) >> last.bits)]; |
519 | 0 | if ((unsigned)(last.bits + here.bits) <= bits) break; |
520 | 0 | PULLBYTE(); |
521 | 0 | } |
522 | 0 | DROPBITS(last.bits); |
523 | 0 | } |
524 | 0 | DROPBITS(here.bits); |
525 | 0 | length = (unsigned)here.val; |
526 | | |
527 | | /* process literal */ |
528 | 0 | if (here.op == 0) { |
529 | 0 | Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? |
530 | 0 | "inflate: literal '%c'\n" : |
531 | 0 | "inflate: literal 0x%02x\n", here.val)); |
532 | 0 | ROOM(); |
533 | 0 | *put++ = (unsigned char)(length); |
534 | 0 | left--; |
535 | 0 | mode = LEN; |
536 | 0 | break; |
537 | 0 | } |
538 | | |
539 | | /* process end of block */ |
540 | 0 | if (here.op & 32) { |
541 | 0 | Tracevv((stderr, "inflate: end of block\n")); |
542 | 0 | mode = TYPE; |
543 | 0 | break; |
544 | 0 | } |
545 | | |
546 | | /* invalid code */ |
547 | 0 | if (here.op & 64) { |
548 | 0 | strm->msg = (char *)"invalid literal/length code"; |
549 | 0 | mode = BAD; |
550 | 0 | break; |
551 | 0 | } |
552 | | |
553 | | /* length code -- get extra bits, if any */ |
554 | 0 | extra = (unsigned)(here.op) & 31; |
555 | 0 | mode = LENEXT; |
556 | | // fallthrough |
557 | |
|
558 | 0 | case LENEXT: |
559 | 0 | if (extra != 0) { |
560 | 0 | NEEDBITS(extra); |
561 | 0 | length += BITS(extra); |
562 | 0 | DROPBITS(extra); |
563 | 0 | } |
564 | 0 | Tracevv((stderr, "inflate: length %lu\n", length)); |
565 | | |
566 | | /* get distance code */ |
567 | 0 | mode = DIST; |
568 | | // fallthrough |
569 | |
|
570 | 0 | case DIST: |
571 | 0 | for (;;) { |
572 | 0 | here = distcode[BITS(distbits)]; |
573 | 0 | if ((unsigned)(here.bits) <= bits) break; |
574 | 0 | PULLBYTE(); |
575 | 0 | } |
576 | 0 | if ((here.op & 0xf0) == 0) { |
577 | 0 | last = here; |
578 | 0 | for (;;) { |
579 | 0 | here = distcode[last.val + |
580 | 0 | (BITS(last.bits + last.op) >> last.bits)]; |
581 | 0 | if ((unsigned)(last.bits + here.bits) <= bits) break; |
582 | 0 | PULLBYTE(); |
583 | 0 | } |
584 | 0 | DROPBITS(last.bits); |
585 | 0 | } |
586 | 0 | DROPBITS(here.bits); |
587 | 0 | if (here.op & 64) { |
588 | 0 | strm->msg = (char *)"invalid distance code"; |
589 | 0 | mode = BAD; |
590 | 0 | break; |
591 | 0 | } |
592 | 0 | offset = (unsigned)here.val; |
593 | | |
594 | | /* get distance extra bits, if any */ |
595 | 0 | extra = (unsigned)(here.op) & 15; |
596 | 0 | mode = DISTEXT; |
597 | | // fallthrough |
598 | |
|
599 | 0 | case DISTEXT: |
600 | 0 | if (extra != 0) { |
601 | 0 | NEEDBITS(extra); |
602 | 0 | offset += BITS(extra); |
603 | 0 | DROPBITS(extra); |
604 | 0 | } |
605 | 0 | if (offset > WSIZE - (wrap ? 0: left)) { |
606 | 0 | strm->msg = (char *)"invalid distance too far back"; |
607 | 0 | mode = BAD; |
608 | 0 | break; |
609 | 0 | } |
610 | 0 | Tracevv((stderr, "inflate: distance %lu\n", offset)); |
611 | | |
612 | | /* copy match from window to output */ |
613 | 0 | mode = MATCH; |
614 | | // fallthrough |
615 | |
|
616 | 0 | case MATCH: |
617 | 0 | do { |
618 | 0 | ROOM(); |
619 | 0 | copy = WSIZE - offset; |
620 | 0 | if (copy < left) { |
621 | 0 | from = put + copy; |
622 | 0 | copy = left - copy; |
623 | 0 | } |
624 | 0 | else { |
625 | 0 | from = put - offset; |
626 | 0 | copy = left; |
627 | 0 | } |
628 | 0 | if (copy > length) copy = length; |
629 | 0 | length -= copy; |
630 | 0 | left -= copy; |
631 | 0 | do { |
632 | 0 | *put++ = *from++; |
633 | 0 | } while (--copy); |
634 | 0 | } while (length != 0); |
635 | 0 | mode = LEN; |
636 | 0 | break; |
637 | | |
638 | 0 | case DONE: |
639 | | /* inflate stream terminated properly -- write leftover output */ |
640 | 0 | ret = Z_STREAM_END; |
641 | 0 | if (left < WSIZE) { |
642 | 0 | if (out(out_desc, window, (unsigned)(WSIZE - left))) |
643 | 0 | ret = Z_BUF_ERROR; |
644 | 0 | } |
645 | 0 | goto inf_leave; |
646 | | |
647 | 0 | case BAD: |
648 | 0 | ret = Z_DATA_ERROR; |
649 | 0 | goto inf_leave; |
650 | | |
651 | 0 | default: /* can't happen, but makes compilers happy */ |
652 | 0 | ret = Z_STREAM_ERROR; |
653 | 0 | goto inf_leave; |
654 | 0 | } |
655 | | |
656 | | /* Return unused input */ |
657 | 0 | inf_leave: |
658 | 0 | strm->next_in = next; |
659 | 0 | strm->avail_in = have; |
660 | 0 | state->left = left; |
661 | |
|
662 | 0 | state->mode = mode; |
663 | 0 | state->wrap = wrap; |
664 | 0 | state->hold = hold; |
665 | 0 | state->bits = bits; |
666 | 0 | state->extra = extra; |
667 | 0 | state->length = length; |
668 | 0 | state->offset = offset; |
669 | 0 | state->lencode = lencode; |
670 | 0 | state->distcode = distcode; |
671 | 0 | state->lenbits = lenbits; |
672 | 0 | state->distbits = distbits; |
673 | 0 | state->last = lastblock; |
674 | 0 | return ret; |
675 | 0 | } |
676 | | |
677 | | int ZEXPORT inflateBack9End(z_stream FAR *strm) |
678 | 0 | { |
679 | 0 | if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) |
680 | 0 | return Z_STREAM_ERROR; |
681 | | // Added by E. Rouault |
682 | 0 | struct inflate_state FAR *state = (struct inflate_state FAR *)strm->state; |
683 | 0 | if (state->window != Z_NULL) ZFREE(strm, state->window); |
684 | 0 | ZFREE(strm, strm->state); |
685 | 0 | strm->state = Z_NULL; |
686 | 0 | Tracev((stderr, "inflate: end\n")); |
687 | 0 | return Z_OK; |
688 | 0 | } |
689 | | |
690 | | // Added by E. Rouault (ported from inflateCopy()) |
691 | | int ZEXPORT inflateBack9Copy(z_streamp dest, z_streamp source) |
692 | 0 | { |
693 | 0 | struct inflate_state FAR *state; |
694 | 0 | struct inflate_state FAR *copy; |
695 | 0 | unsigned char FAR *window; |
696 | | |
697 | | /* check input */ |
698 | 0 | if (/*inflateStateCheck(source) ||*/ dest == Z_NULL) |
699 | 0 | return Z_STREAM_ERROR; |
700 | 0 | state = (struct inflate_state FAR *)source->state; |
701 | | |
702 | | /* allocate space */ |
703 | 0 | copy = (struct inflate_state FAR *) |
704 | 0 | ZALLOC(source, 1, sizeof(struct inflate_state)); |
705 | 0 | if (copy == Z_NULL) return Z_MEM_ERROR; |
706 | 0 | window = Z_NULL; |
707 | 0 | if (state->window != Z_NULL) { |
708 | 0 | window = (unsigned char FAR *) |
709 | 0 | ZALLOC(source, WSIZE, sizeof(unsigned char)); |
710 | 0 | if (window == Z_NULL) { |
711 | 0 | ZFREE(source, copy); |
712 | 0 | return Z_MEM_ERROR; |
713 | 0 | } |
714 | 0 | } |
715 | | |
716 | | /* copy state */ |
717 | 0 | zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); |
718 | 0 | zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); |
719 | |
|
720 | 0 | if (state->lencode >= state->codes && |
721 | 0 | state->lencode <= state->codes + ENOUGH - 1) { |
722 | 0 | copy->lencode = copy->codes + (state->lencode - state->codes); |
723 | 0 | copy->distcode = copy->codes + (state->distcode - state->codes); |
724 | 0 | } |
725 | 0 | if( state->next ) |
726 | 0 | { |
727 | 0 | assert(state->next >= state->codes); |
728 | 0 | copy->next = copy->codes + (state->next - state->codes); |
729 | 0 | } |
730 | 0 | if (window != Z_NULL) { |
731 | 0 | zmemcpy(window, state->window, WSIZE); |
732 | 0 | } |
733 | 0 | copy->window = window; |
734 | 0 | dest->state = (struct internal_state FAR *)copy; |
735 | 0 | return Z_OK; |
736 | 0 | } |