This source file includes following definitions.
- inflateBackInit_
- fixedtables
- inflateBack
- inflateBackEnd
1
2
3
4
5
6
7
8
9
10
11
12
13 #include "zutil.h"
14 #include "inftrees.h"
15 #include "inflate.h"
16 #include "inffast.h"
17
18
19 local void fixedtables OF((struct inflate_state FAR *state));
20
21
22
23
24
25
26
27
28 int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
29 z_streamp strm;
30 int windowBits;
31 unsigned char FAR *window;
32 const char *version;
33 int stream_size;
34 {
35 struct inflate_state FAR *state;
36
37 if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
38 stream_size != (int)(sizeof(z_stream)))
39 return Z_VERSION_ERROR;
40 if (strm == Z_NULL || window == Z_NULL ||
41 windowBits < 8 || windowBits > 15)
42 return Z_STREAM_ERROR;
43 strm->msg = Z_NULL;
44 if (strm->zalloc == (alloc_func)0) {
45 strm->zalloc = zcalloc;
46 strm->opaque = (voidpf)0;
47 }
48 if (strm->zfree == (free_func)0) strm->zfree = zcfree;
49 state = (struct inflate_state FAR *)ZALLOC(strm, 1,
50 sizeof(struct inflate_state));
51 if (state == Z_NULL) return Z_MEM_ERROR;
52 Tracev((stderr, "inflate: allocated\n"));
53 strm->state = (struct internal_state FAR *)state;
54 state->dmax = 32768U;
55 state->wbits = windowBits;
56 state->wsize = 1U << windowBits;
57 state->window = window;
58 state->write = 0;
59 state->whave = 0;
60 return Z_OK;
61 }
62
63
64
65
66
67
68
69
70
71
72
73 local void fixedtables(state)
74 struct inflate_state FAR *state;
75 {
76 #ifdef BUILDFIXED
77 static int virgin = 1;
78 static code *lenfix, *distfix;
79 static code fixed[544];
80
81
82 if (virgin) {
83 unsigned sym, bits;
84 static code *next;
85
86
87 sym = 0;
88 while (sym < 144) state->lens[sym++] = 8;
89 while (sym < 256) state->lens[sym++] = 9;
90 while (sym < 280) state->lens[sym++] = 7;
91 while (sym < 288) state->lens[sym++] = 8;
92 next = fixed;
93 lenfix = next;
94 bits = 9;
95 inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
96
97
98 sym = 0;
99 while (sym < 32) state->lens[sym++] = 5;
100 distfix = next;
101 bits = 5;
102 inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
103
104
105 virgin = 0;
106 }
107 #else
108 # include "inffixed.h"
109 #endif
110 state->lencode = lenfix;
111 state->lenbits = 9;
112 state->distcode = distfix;
113 state->distbits = 5;
114 }
115
116
117
118
119 #define LOAD() \
120 do { \
121 put = strm->next_out; \
122 left = strm->avail_out; \
123 next = strm->next_in; \
124 have = strm->avail_in; \
125 hold = state->hold; \
126 bits = state->bits; \
127 } while (0)
128
129
130 #define RESTORE() \
131 do { \
132 strm->next_out = put; \
133 strm->avail_out = left; \
134 strm->next_in = next; \
135 strm->avail_in = have; \
136 state->hold = hold; \
137 state->bits = bits; \
138 } while (0)
139
140
141 #define INITBITS() \
142 do { \
143 hold = 0; \
144 bits = 0; \
145 } while (0)
146
147
148
149 #define PULL() \
150 do { \
151 if (have == 0) { \
152 have = in(in_desc, &next); \
153 if (have == 0) { \
154 next = Z_NULL; \
155 ret = Z_BUF_ERROR; \
156 goto inf_leave; \
157 } \
158 } \
159 } while (0)
160
161
162
163 #define PULLBYTE() \
164 do { \
165 PULL(); \
166 have--; \
167 hold += (unsigned long)(*next++) << bits; \
168 bits += 8; \
169 } while (0)
170
171
172
173
174 #define NEEDBITS(n) \
175 do { \
176 while (bits < (unsigned)(n)) \
177 PULLBYTE(); \
178 } while (0)
179
180
181 #define BITS(n) \
182 ((unsigned)hold & ((1U << (n)) - 1))
183
184
185 #define DROPBITS(n) \
186 do { \
187 hold >>= (n); \
188 bits -= (unsigned)(n); \
189 } while (0)
190
191
192 #define BYTEBITS() \
193 do { \
194 hold >>= bits & 7; \
195 bits -= bits & 7; \
196 } while (0)
197
198
199
200
201 #define ROOM() \
202 do { \
203 if (left == 0) { \
204 put = state->window; \
205 left = state->wsize; \
206 state->whave = left; \
207 if (out(out_desc, put, left)) { \
208 ret = Z_BUF_ERROR; \
209 goto inf_leave; \
210 } \
211 } \
212 } while (0)
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241 int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
242 z_streamp strm;
243 in_func in;
244 void FAR *in_desc;
245 out_func out;
246 void FAR *out_desc;
247 {
248 struct inflate_state FAR *state;
249 unsigned char FAR *next;
250 unsigned char FAR *put;
251 unsigned have, left;
252 unsigned long hold;
253 unsigned bits;
254 unsigned copy;
255 unsigned char FAR *from;
256 code this;
257 code last;
258 unsigned len;
259 int ret;
260 static const unsigned short order[19] =
261 {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
262
263
264 if (strm == Z_NULL || strm->state == Z_NULL)
265 return Z_STREAM_ERROR;
266 state = (struct inflate_state FAR *)strm->state;
267
268
269 strm->msg = Z_NULL;
270 state->mode = TYPE;
271 state->last = 0;
272 state->whave = 0;
273 next = strm->next_in;
274 have = next != Z_NULL ? strm->avail_in : 0;
275 hold = 0;
276 bits = 0;
277 put = state->window;
278 left = state->wsize;
279
280
281 for (;;)
282 switch (state->mode) {
283 case TYPE:
284
285 if (state->last) {
286 BYTEBITS();
287 state->mode = DONE;
288 break;
289 }
290 NEEDBITS(3);
291 state->last = BITS(1);
292 DROPBITS(1);
293 switch (BITS(2)) {
294 case 0:
295 Tracev((stderr, "inflate: stored block%s\n",
296 state->last ? " (last)" : ""));
297 state->mode = STORED;
298 break;
299 case 1:
300 fixedtables(state);
301 Tracev((stderr, "inflate: fixed codes block%s\n",
302 state->last ? " (last)" : ""));
303 state->mode = LEN;
304 break;
305 case 2:
306 Tracev((stderr, "inflate: dynamic codes block%s\n",
307 state->last ? " (last)" : ""));
308 state->mode = TABLE;
309 break;
310 case 3:
311 #ifdef SMALL
312 strm->msg = "error";
313 #else
314 strm->msg = (char *)"invalid block type";
315 #endif
316 state->mode = BAD;
317 }
318 DROPBITS(2);
319 break;
320
321 case STORED:
322
323 BYTEBITS();
324 NEEDBITS(32);
325 if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
326 #ifdef SMALL
327 strm->msg = "error";
328 #else
329 strm->msg = (char *)"invalid stored block lengths";
330 #endif
331 state->mode = BAD;
332 break;
333 }
334 state->length = (unsigned)hold & 0xffff;
335 Tracev((stderr, "inflate: stored length %u\n",
336 state->length));
337 INITBITS();
338
339
340 while (state->length != 0) {
341 copy = state->length;
342 PULL();
343 ROOM();
344 if (copy > have) copy = have;
345 if (copy > left) copy = left;
346 zmemcpy(put, next, copy);
347 have -= copy;
348 next += copy;
349 left -= copy;
350 put += copy;
351 state->length -= copy;
352 }
353 Tracev((stderr, "inflate: stored end\n"));
354 state->mode = TYPE;
355 break;
356
357 case TABLE:
358
359 NEEDBITS(14);
360 state->nlen = BITS(5) + 257;
361 DROPBITS(5);
362 state->ndist = BITS(5) + 1;
363 DROPBITS(5);
364 state->ncode = BITS(4) + 4;
365 DROPBITS(4);
366 #ifndef PKZIP_BUG_WORKAROUND
367 if (state->nlen > 286 || state->ndist > 30) {
368 #ifdef SMALL
369 strm->msg = "error";
370 #else
371 strm->msg = (char *)"too many length or distance symbols";
372 #endif
373 state->mode = BAD;
374 break;
375 }
376 #endif
377 Tracev((stderr, "inflate: table sizes ok\n"));
378
379
380 state->have = 0;
381 while (state->have < state->ncode) {
382 NEEDBITS(3);
383 state->lens[order[state->have++]] = (unsigned short)BITS(3);
384 DROPBITS(3);
385 }
386 while (state->have < 19)
387 state->lens[order[state->have++]] = 0;
388 state->next = state->codes;
389 state->lencode = (code const FAR *)(state->next);
390 state->lenbits = 7;
391 ret = inflate_table(CODES, state->lens, 19, &(state->next),
392 &(state->lenbits), state->work);
393 if (ret) {
394 strm->msg = (char *)"invalid code lengths set";
395 state->mode = BAD;
396 break;
397 }
398 Tracev((stderr, "inflate: code lengths ok\n"));
399
400
401 state->have = 0;
402 while (state->have < state->nlen + state->ndist) {
403 for (;;) {
404 this = state->lencode[BITS(state->lenbits)];
405 if ((unsigned)(this.bits) <= bits) break;
406 PULLBYTE();
407 }
408 if (this.val < 16) {
409 NEEDBITS(this.bits);
410 DROPBITS(this.bits);
411 state->lens[state->have++] = this.val;
412 }
413 else {
414 if (this.val == 16) {
415 NEEDBITS(this.bits + 2);
416 DROPBITS(this.bits);
417 if (state->have == 0) {
418 strm->msg = (char *)"invalid bit length repeat";
419 state->mode = BAD;
420 break;
421 }
422 len = (unsigned)(state->lens[state->have - 1]);
423 copy = 3 + BITS(2);
424 DROPBITS(2);
425 }
426 else if (this.val == 17) {
427 NEEDBITS(this.bits + 3);
428 DROPBITS(this.bits);
429 len = 0;
430 copy = 3 + BITS(3);
431 DROPBITS(3);
432 }
433 else {
434 NEEDBITS(this.bits + 7);
435 DROPBITS(this.bits);
436 len = 0;
437 copy = 11 + BITS(7);
438 DROPBITS(7);
439 }
440 if (state->have + copy > state->nlen + state->ndist) {
441 strm->msg = (char *)"invalid bit length repeat";
442 state->mode = BAD;
443 break;
444 }
445 while (copy--)
446 state->lens[state->have++] = (unsigned short)len;
447 }
448 }
449
450
451 if (state->mode == BAD) break;
452
453
454 state->next = state->codes;
455 state->lencode = (code const FAR *)(state->next);
456 state->lenbits = 9;
457 ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
458 &(state->lenbits), state->work);
459 if (ret) {
460 strm->msg = (char *)"invalid literal/lengths set";
461 state->mode = BAD;
462 break;
463 }
464 state->distcode = (code const FAR *)(state->next);
465 state->distbits = 6;
466 ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
467 &(state->next), &(state->distbits), state->work);
468 if (ret) {
469 strm->msg = (char *)"invalid distances set";
470 state->mode = BAD;
471 break;
472 }
473 Tracev((stderr, "inflate: codes ok\n"));
474 state->mode = LEN;
475
476 case LEN:
477 #ifndef SLOW
478
479 if (have >= 6 && left >= 258) {
480 RESTORE();
481 if (state->whave < state->wsize)
482 state->whave = state->wsize - left;
483 inflate_fast(strm, state->wsize);
484 LOAD();
485 break;
486 }
487 #endif
488
489
490 for (;;) {
491 this = state->lencode[BITS(state->lenbits)];
492 if ((unsigned)(this.bits) <= bits) break;
493 PULLBYTE();
494 }
495 if (this.op && (this.op & 0xf0) == 0) {
496 last = this;
497 for (;;) {
498 this = state->lencode[last.val +
499 (BITS(last.bits + last.op) >> last.bits)];
500 if ((unsigned)(last.bits + this.bits) <= bits) break;
501 PULLBYTE();
502 }
503 DROPBITS(last.bits);
504 }
505 DROPBITS(this.bits);
506 state->length = (unsigned)this.val;
507
508
509 if (this.op == 0) {
510 Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
511 "inflate: literal '%c'\n" :
512 "inflate: literal 0x%02x\n", this.val));
513 ROOM();
514 *put++ = (unsigned char)(state->length);
515 left--;
516 state->mode = LEN;
517 break;
518 }
519
520
521 if (this.op & 32) {
522 Tracevv((stderr, "inflate: end of block\n"));
523 state->mode = TYPE;
524 break;
525 }
526
527
528 if (this.op & 64) {
529 strm->msg = (char *)"invalid literal/length code";
530 state->mode = BAD;
531 break;
532 }
533
534
535 state->extra = (unsigned)(this.op) & 15;
536 if (state->extra != 0) {
537 NEEDBITS(state->extra);
538 state->length += BITS(state->extra);
539 DROPBITS(state->extra);
540 }
541 Tracevv((stderr, "inflate: length %u\n", state->length));
542
543
544 for (;;) {
545 this = state->distcode[BITS(state->distbits)];
546 if ((unsigned)(this.bits) <= bits) break;
547 PULLBYTE();
548 }
549 if ((this.op & 0xf0) == 0) {
550 last = this;
551 for (;;) {
552 this = state->distcode[last.val +
553 (BITS(last.bits + last.op) >> last.bits)];
554 if ((unsigned)(last.bits + this.bits) <= bits) break;
555 PULLBYTE();
556 }
557 DROPBITS(last.bits);
558 }
559 DROPBITS(this.bits);
560 if (this.op & 64) {
561 strm->msg = (char *)"invalid distance code";
562 state->mode = BAD;
563 break;
564 }
565 state->offset = (unsigned)this.val;
566
567
568 state->extra = (unsigned)(this.op) & 15;
569 if (state->extra != 0) {
570 NEEDBITS(state->extra);
571 state->offset += BITS(state->extra);
572 DROPBITS(state->extra);
573 }
574 if (state->offset > state->wsize - (state->whave < state->wsize ?
575 left : 0)) {
576 strm->msg = (char *)"invalid distance too far back";
577 state->mode = BAD;
578 break;
579 }
580 Tracevv((stderr, "inflate: distance %u\n", state->offset));
581
582
583 do {
584 ROOM();
585 copy = state->wsize - state->offset;
586 if (copy < left) {
587 from = put + copy;
588 copy = left - copy;
589 }
590 else {
591 from = put - state->offset;
592 copy = left;
593 }
594 if (copy > state->length) copy = state->length;
595 state->length -= copy;
596 left -= copy;
597 do {
598 *put++ = *from++;
599 } while (--copy);
600 } while (state->length != 0);
601 break;
602
603 case DONE:
604
605 ret = Z_STREAM_END;
606 if (left < state->wsize) {
607 if (out(out_desc, state->window, state->wsize - left))
608 ret = Z_BUF_ERROR;
609 }
610 goto inf_leave;
611
612 case BAD:
613 ret = Z_DATA_ERROR;
614 goto inf_leave;
615
616 default:
617 ret = Z_STREAM_ERROR;
618 goto inf_leave;
619 }
620
621
622 inf_leave:
623 strm->next_in = next;
624 strm->avail_in = have;
625 return ret;
626 }
627
628 int ZEXPORT inflateBackEnd(strm)
629 z_streamp strm;
630 {
631 if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
632 return Z_STREAM_ERROR;
633 ZFREE(strm, strm->state);
634 strm->state = Z_NULL;
635 Tracev((stderr, "inflate: end\n"));
636 return Z_OK;
637 }