• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* infback.c -- inflate using a call-back interface
2  * Copyright (C) 1995-2005 Mark Adler
3  * For conditions of distribution and use, see copyright notice in zlib.h
4  */
5 
6 /*
7    This code is largely copied from inflate.c.  Normally either infback.o or
8    inflate.o would be linked into an application--not both.  The interface
9    with inffast.c is retained so that optimized assembler-coded versions of
10    inflate_fast() can be used with either inflate.c or infback.c.
11  */
12 
13 #include "zutil.h"
14 #include "inftrees.h"
15 #include "inflate.h"
16 #include "inffast.h"
17 
18 /* function prototypes */
19 local void fixedtables OF((struct inflate_state FAR *state));
20 
21 /*
22    strm provides memory allocation functions in zalloc and zfree, or
23    Z_NULL to use the library memory allocation functions.
24 
25    windowBits is in the range 8..15, and window is a user-supplied
26    window and output buffer that is 2**windowBits bytes.
27  */
inflateBackInit_(strm,windowBits,window,version,stream_size)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;                 /* in case we return an error */
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    Return state with length and distance decoding tables and index sizes set to
65    fixed code decoding.  Normally this returns fixed tables from inffixed.h.
66    If BUILDFIXED is defined, then instead this routine builds the tables the
67    first time it's called, and returns those tables the first time and
68    thereafter.  This reduces the size of the code by about 2K bytes, in
69    exchange for a little execution time.  However, BUILDFIXED should not be
70    used for threaded applications, since the rewriting of the tables and virgin
71    may not be thread-safe.
72  */
fixedtables(state)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     /* build fixed huffman tables if first call (may not be thread safe) */
82     if (virgin) {
83         unsigned sym, bits;
84         static code *next;
85 
86         /* literal/length table */
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         /* distance table */
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         /* do this just once */
105         virgin = 0;
106     }
107 #else /* !BUILDFIXED */
108 #   include "inffixed.h"
109 #endif /* BUILDFIXED */
110     state->lencode = lenfix;
111     state->lenbits = 9;
112     state->distcode = distfix;
113     state->distbits = 5;
114 }
115 
116 /* Macros for inflateBack(): */
117 
118 /* Load returned state from inflate_fast() */
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 /* Set state from registers for inflate_fast() */
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 /* Clear the input bit accumulator */
141 #define INITBITS() \
142     do { \
143         hold = 0; \
144         bits = 0; \
145     } while (0)
146 
147 /* Assure that some input is available.  If input is requested, but denied,
148    then return a Z_BUF_ERROR from inflateBack(). */
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 /* Get a byte of input into the bit accumulator, or return from inflateBack()
162    with an error if there is no input available. */
163 #define PULLBYTE() \
164     do { \
165         PULL(); \
166         have--; \
167         hold += (unsigned long)(*next++) << bits; \
168         bits += 8; \
169     } while (0)
170 
171 /* Assure that there are at least n bits in the bit accumulator.  If there is
172    not enough available input to do that, then return from inflateBack() with
173    an error. */
174 #define NEEDBITS(n) \
175     do { \
176         while (bits < (unsigned)(n)) \
177             PULLBYTE(); \
178     } while (0)
179 
180 /* Return the low n bits of the bit accumulator (n < 16) */
181 #define BITS(n) \
182     ((unsigned)hold & ((1U << (n)) - 1))
183 
184 /* Remove n bits from the bit accumulator */
185 #define DROPBITS(n) \
186     do { \
187         hold >>= (n); \
188         bits -= (unsigned)(n); \
189     } while (0)
190 
191 /* Remove zero to seven bits as needed to go to a byte boundary */
192 #define BYTEBITS() \
193     do { \
194         hold >>= bits & 7; \
195         bits -= bits & 7; \
196     } while (0)
197 
198 /* Assure that some output space is available, by writing out the window
199    if it's full.  If the write fails, return from inflateBack() with a
200    Z_BUF_ERROR. */
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    strm provides the memory allocation functions and window buffer on input,
216    and provides information on the unused input on return.  For Z_DATA_ERROR
217    returns, strm will also provide an error message.
218 
219    in() and out() are the call-back input and output functions.  When
220    inflateBack() needs more input, it calls in().  When inflateBack() has
221    filled the window with output, or when it completes with data in the
222    window, it calls out() to write out the data.  The application must not
223    change the provided input until in() is called again or inflateBack()
224    returns.  The application must not change the window/output buffer until
225    inflateBack() returns.
226 
227    in() and out() are called with a descriptor parameter provided in the
228    inflateBack() call.  This parameter can be a structure that provides the
229    information required to do the read or write, as well as accumulated
230    information on the input and output such as totals and check values.
231 
232    in() should return zero on failure.  out() should return non-zero on
233    failure.  If either in() or out() fails, than inflateBack() returns a
234    Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
235    was in() or out() that caused in the error.  Otherwise,  inflateBack()
236    returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
237    error, or Z_MEM_ERROR if it could not allocate memory for the state.
238    inflateBack() can also return Z_STREAM_ERROR if the input parameters
239    are not correct, i.e. strm is Z_NULL or the state was not initialized.
240  */
inflateBack(strm,in,in_desc,out,out_desc)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;    /* next input */
250     unsigned char FAR *put;     /* next output */
251     unsigned have, left;        /* available input and output */
252     unsigned long hold;         /* bit buffer */
253     unsigned bits;              /* bits in bit buffer */
254     unsigned copy;              /* number of stored or match bytes to copy */
255     unsigned char FAR *from;    /* where to copy match bytes from */
256     code this;                  /* current decoding table entry */
257     code last;                  /* parent table entry */
258     unsigned len;               /* length to copy for repeats, bits to drop */
259     int ret;                    /* return code */
260     static const unsigned short order[19] = /* permutation of code lengths */
261         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
262 
263     /* Check that the strm exists and that the state was initialized */
264     if (strm == Z_NULL || strm->state == Z_NULL)
265         return Z_STREAM_ERROR;
266     state = (struct inflate_state FAR *)strm->state;
267 
268     /* Reset the state */
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     /* Inflate until end of block marked as last */
281     for (;;)
282         switch (state->mode) {
283         case TYPE:
284             /* determine and dispatch block type */
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:                             /* stored block */
295                 Tracev((stderr, "inflate:     stored block%s\n",
296                         state->last ? " (last)" : ""));
297                 state->mode = STORED;
298                 break;
299             case 1:                             /* fixed block */
300                 fixedtables(state);
301                 Tracev((stderr, "inflate:     fixed codes block%s\n",
302                         state->last ? " (last)" : ""));
303                 state->mode = LEN;              /* decode codes */
304                 break;
305             case 2:                             /* dynamic block */
306                 Tracev((stderr, "inflate:     dynamic codes block%s\n",
307                         state->last ? " (last)" : ""));
308                 state->mode = TABLE;
309                 break;
310             case 3:
311                 strm->msg = (char *)"invalid block type";
312                 state->mode = BAD;
313             }
314             DROPBITS(2);
315             break;
316 
317         case STORED:
318             /* get and verify stored block length */
319             BYTEBITS();                         /* go to byte boundary */
320             NEEDBITS(32);
321             if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
322                 strm->msg = (char *)"invalid stored block lengths";
323                 state->mode = BAD;
324                 break;
325             }
326             state->length = (unsigned)hold & 0xffff;
327             Tracev((stderr, "inflate:       stored length %u\n",
328                     state->length));
329             INITBITS();
330 
331             /* copy stored block from input to output */
332             while (state->length != 0) {
333                 copy = state->length;
334                 PULL();
335                 ROOM();
336                 if (copy > have) copy = have;
337                 if (copy > left) copy = left;
338                 zmemcpy(put, next, copy);
339                 have -= copy;
340                 next += copy;
341                 left -= copy;
342                 put += copy;
343                 state->length -= copy;
344             }
345             Tracev((stderr, "inflate:       stored end\n"));
346             state->mode = TYPE;
347             break;
348 
349         case TABLE:
350             /* get dynamic table entries descriptor */
351             NEEDBITS(14);
352             state->nlen = BITS(5) + 257;
353             DROPBITS(5);
354             state->ndist = BITS(5) + 1;
355             DROPBITS(5);
356             state->ncode = BITS(4) + 4;
357             DROPBITS(4);
358 #ifndef PKZIP_BUG_WORKAROUND
359             if (state->nlen > 286 || state->ndist > 30) {
360                 strm->msg = (char *)"too many length or distance symbols";
361                 state->mode = BAD;
362                 break;
363             }
364 #endif
365             Tracev((stderr, "inflate:       table sizes ok\n"));
366 
367             /* get code length code lengths (not a typo) */
368             state->have = 0;
369             while (state->have < state->ncode) {
370                 NEEDBITS(3);
371                 state->lens[order[state->have++]] = (unsigned short)BITS(3);
372                 DROPBITS(3);
373             }
374             while (state->have < 19)
375                 state->lens[order[state->have++]] = 0;
376             state->next = state->codes;
377             state->lencode = (code const FAR *)(state->next);
378             state->lenbits = 7;
379             ret = inflate_table(CODES, state->lens, 19, &(state->next),
380                                 &(state->lenbits), state->work);
381             if (ret) {
382                 strm->msg = (char *)"invalid code lengths set";
383                 state->mode = BAD;
384                 break;
385             }
386             Tracev((stderr, "inflate:       code lengths ok\n"));
387 
388             /* get length and distance code code lengths */
389             state->have = 0;
390             while (state->have < state->nlen + state->ndist) {
391                 for (;;) {
392                     this = state->lencode[BITS(state->lenbits)];
393                     if ((unsigned)(this.bits) <= bits) break;
394                     PULLBYTE();
395                 }
396                 if (this.val < 16) {
397                     NEEDBITS(this.bits);
398                     DROPBITS(this.bits);
399                     state->lens[state->have++] = this.val;
400                 }
401                 else {
402                     if (this.val == 16) {
403                         NEEDBITS(this.bits + 2);
404                         DROPBITS(this.bits);
405                         if (state->have == 0) {
406                             strm->msg = (char *)"invalid bit length repeat";
407                             state->mode = BAD;
408                             break;
409                         }
410                         len = (unsigned)(state->lens[state->have - 1]);
411                         copy = 3 + BITS(2);
412                         DROPBITS(2);
413                     }
414                     else if (this.val == 17) {
415                         NEEDBITS(this.bits + 3);
416                         DROPBITS(this.bits);
417                         len = 0;
418                         copy = 3 + BITS(3);
419                         DROPBITS(3);
420                     }
421                     else {
422                         NEEDBITS(this.bits + 7);
423                         DROPBITS(this.bits);
424                         len = 0;
425                         copy = 11 + BITS(7);
426                         DROPBITS(7);
427                     }
428                     if (state->have + copy > state->nlen + state->ndist) {
429                         strm->msg = (char *)"invalid bit length repeat";
430                         state->mode = BAD;
431                         break;
432                     }
433                     while (copy--)
434                         state->lens[state->have++] = (unsigned short)len;
435                 }
436             }
437 
438             /* handle error breaks in while */
439             if (state->mode == BAD) break;
440 
441             /* build code tables */
442             state->next = state->codes;
443             state->lencode = (code const FAR *)(state->next);
444             state->lenbits = 9;
445             ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
446                                 &(state->lenbits), state->work);
447             if (ret) {
448                 strm->msg = (char *)"invalid literal/lengths set";
449                 state->mode = BAD;
450                 break;
451             }
452             state->distcode = (code const FAR *)(state->next);
453             state->distbits = 6;
454             ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
455                             &(state->next), &(state->distbits), state->work);
456             if (ret) {
457                 strm->msg = (char *)"invalid distances set";
458                 state->mode = BAD;
459                 break;
460             }
461             Tracev((stderr, "inflate:       codes ok\n"));
462             state->mode = LEN;
463 
464         case LEN:
465             /* use inflate_fast() if we have enough input and output */
466             if (have >= 6 && left >= 258) {
467                 RESTORE();
468                 if (state->whave < state->wsize)
469                     state->whave = state->wsize - left;
470                 inflate_fast(strm, state->wsize);
471                 LOAD();
472                 break;
473             }
474 
475             /* get a literal, length, or end-of-block code */
476             for (;;) {
477                 this = state->lencode[BITS(state->lenbits)];
478                 if ((unsigned)(this.bits) <= bits) break;
479                 PULLBYTE();
480             }
481             if (this.op && (this.op & 0xf0) == 0) {
482                 last = this;
483                 for (;;) {
484                     this = state->lencode[last.val +
485                             (BITS(last.bits + last.op) >> last.bits)];
486                     if ((unsigned)(last.bits + this.bits) <= bits) break;
487                     PULLBYTE();
488                 }
489                 DROPBITS(last.bits);
490             }
491             DROPBITS(this.bits);
492             state->length = (unsigned)this.val;
493 
494             /* process literal */
495             if (this.op == 0) {
496                 Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
497                         "inflate:         literal '%c'\n" :
498                         "inflate:         literal 0x%02x\n", this.val));
499                 ROOM();
500                 *put++ = (unsigned char)(state->length);
501                 left--;
502                 state->mode = LEN;
503                 break;
504             }
505 
506             /* process end of block */
507             if (this.op & 32) {
508                 Tracevv((stderr, "inflate:         end of block\n"));
509                 state->mode = TYPE;
510                 break;
511             }
512 
513             /* invalid code */
514             if (this.op & 64) {
515                 strm->msg = (char *)"invalid literal/length code";
516                 state->mode = BAD;
517                 break;
518             }
519 
520             /* length code -- get extra bits, if any */
521             state->extra = (unsigned)(this.op) & 15;
522             if (state->extra != 0) {
523                 NEEDBITS(state->extra);
524                 state->length += BITS(state->extra);
525                 DROPBITS(state->extra);
526             }
527             Tracevv((stderr, "inflate:         length %u\n", state->length));
528 
529             /* get distance code */
530             for (;;) {
531                 this = state->distcode[BITS(state->distbits)];
532                 if ((unsigned)(this.bits) <= bits) break;
533                 PULLBYTE();
534             }
535             if ((this.op & 0xf0) == 0) {
536                 last = this;
537                 for (;;) {
538                     this = state->distcode[last.val +
539                             (BITS(last.bits + last.op) >> last.bits)];
540                     if ((unsigned)(last.bits + this.bits) <= bits) break;
541                     PULLBYTE();
542                 }
543                 DROPBITS(last.bits);
544             }
545             DROPBITS(this.bits);
546             if (this.op & 64) {
547                 strm->msg = (char *)"invalid distance code";
548                 state->mode = BAD;
549                 break;
550             }
551             state->offset = (unsigned)this.val;
552 
553             /* get distance extra bits, if any */
554             state->extra = (unsigned)(this.op) & 15;
555             if (state->extra != 0) {
556                 NEEDBITS(state->extra);
557                 state->offset += BITS(state->extra);
558                 DROPBITS(state->extra);
559             }
560             if (state->offset > state->wsize - (state->whave < state->wsize ?
561                                                 left : 0)) {
562                 strm->msg = (char *)"invalid distance too far back";
563                 state->mode = BAD;
564                 break;
565             }
566             Tracevv((stderr, "inflate:         distance %u\n", state->offset));
567 
568             /* copy match from window to output */
569             do {
570                 ROOM();
571                 copy = state->wsize - state->offset;
572                 if (copy < left) {
573                     from = put + copy;
574                     copy = left - copy;
575                 }
576                 else {
577                     from = put - state->offset;
578                     copy = left;
579                 }
580                 if (copy > state->length) copy = state->length;
581                 state->length -= copy;
582                 left -= copy;
583                 do {
584                     *put++ = *from++;
585                 } while (--copy);
586             } while (state->length != 0);
587             break;
588 
589         case DONE:
590             /* inflate stream terminated properly -- write leftover output */
591             ret = Z_STREAM_END;
592             if (left < state->wsize) {
593                 if (out(out_desc, state->window, state->wsize - left))
594                     ret = Z_BUF_ERROR;
595             }
596             goto inf_leave;
597 
598         case BAD:
599             ret = Z_DATA_ERROR;
600             goto inf_leave;
601 
602         default:                /* can't happen, but makes compilers happy */
603             ret = Z_STREAM_ERROR;
604             goto inf_leave;
605         }
606 
607     /* Return unused input */
608   inf_leave:
609     strm->next_in = next;
610     strm->avail_in = have;
611     return ret;
612 }
613 
inflateBackEnd(strm)614 int ZEXPORT inflateBackEnd(strm)
615 z_streamp strm;
616 {
617     if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
618         return Z_STREAM_ERROR;
619     ZFREE(strm, strm->state);
620     strm->state = Z_NULL;
621     Tracev((stderr, "inflate: end\n"));
622     return Z_OK;
623 }
624