• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* infback.c -- inflate using a call-back interface
2  * Copyright (C) 1995-2016 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 "zbuild.h"
14 #include "zutil.h"
15 #include "inftrees.h"
16 #include "inflate.h"
17 #include "inffast.h"
18 #include "inflate_p.h"
19 #include "functable.h"
20 
21 /*
22    strm provides memory allocation functions in zalloc and zfree, or
23    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  */
PREFIX(inflateBackInit_)28 int32_t Z_EXPORT PREFIX(inflateBackInit_)(PREFIX3(stream) *strm, int32_t windowBits, uint8_t *window,
29                               const char *version, int32_t stream_size) {
30     struct inflate_state *state;
31 
32     if (version == NULL || version[0] != PREFIX2(VERSION)[0] || stream_size != (int)(sizeof(PREFIX3(stream))))
33         return Z_VERSION_ERROR;
34     if (strm == NULL || window == NULL || windowBits < 8 || windowBits > 15)
35         return Z_STREAM_ERROR;
36     strm->msg = NULL;                   /* in case we return an error */
37     if (strm->zalloc == NULL) {
38         strm->zalloc = zng_calloc;
39         strm->opaque = NULL;
40     }
41     if (strm->zfree == NULL)
42         strm->zfree = zng_cfree;
43     state = (struct inflate_state *) ZALLOC(strm, 1, sizeof(struct inflate_state));
44     if (state == NULL)
45         return Z_MEM_ERROR;
46     Tracev((stderr, "inflate: allocated\n"));
47     strm->state = (struct internal_state *)state;
48     state->dmax = 32768U;
49     state->wbits = (unsigned int)windowBits;
50     state->wsize = 1U << windowBits;
51     state->window = window;
52     state->wnext = 0;
53     state->whave = 0;
54     state->chunksize = functable.chunksize();
55     return Z_OK;
56 }
57 
58 /*
59    Private macros for inflateBack()
60    Look in inflate_p.h for macros shared with inflate()
61 */
62 
63 /* Assure that some input is available.  If input is requested, but denied,
64    then return a Z_BUF_ERROR from inflateBack(). */
65 #define PULL() \
66     do { \
67         if (have == 0) { \
68             have = in(in_desc, &next); \
69             if (have == 0) { \
70                 next = NULL; \
71                 ret = Z_BUF_ERROR; \
72                 goto inf_leave; \
73             } \
74         } \
75     } while (0)
76 
77 /* Get a byte of input into the bit accumulator, or return from inflateBack()
78    with an error if there is no input available. */
79 #define PULLBYTE() \
80     do { \
81         PULL(); \
82         have--; \
83         hold += (*next++ << bits); \
84         bits += 8; \
85     } while (0)
86 
87 /* Assure that some output space is available, by writing out the window
88    if it's full.  If the write fails, return from inflateBack() with a
89    Z_BUF_ERROR. */
90 #define ROOM() \
91     do { \
92         if (left == 0) { \
93             put = state->window; \
94             left = state->wsize; \
95             state->whave = left; \
96             if (out(out_desc, put, left)) { \
97                 ret = Z_BUF_ERROR; \
98                 goto inf_leave; \
99             } \
100         } \
101     } while (0)
102 
103 /*
104    strm provides the memory allocation functions and window buffer on input,
105    and provides information on the unused input on return.  For Z_DATA_ERROR
106    returns, strm will also provide an error message.
107 
108    in() and out() are the call-back input and output functions.  When
109    inflateBack() needs more input, it calls in().  When inflateBack() has
110    filled the window with output, or when it completes with data in the
111    window, it calls out() to write out the data.  The application must not
112    change the provided input until in() is called again or inflateBack()
113    returns.  The application must not change the window/output buffer until
114    inflateBack() returns.
115 
116    in() and out() are called with a descriptor parameter provided in the
117    inflateBack() call.  This parameter can be a structure that provides the
118    information required to do the read or write, as well as accumulated
119    information on the input and output such as totals and check values.
120 
121    in() should return zero on failure.  out() should return non-zero on
122    failure.  If either in() or out() fails, than inflateBack() returns a
123    Z_BUF_ERROR.  strm->next_in can be checked for NULL to see whether it
124    was in() or out() that caused in the error.  Otherwise, inflateBack()
125    returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
126    error, or Z_MEM_ERROR if it could not allocate memory for the state.
127    inflateBack() can also return Z_STREAM_ERROR if the input parameters
128    are not correct, i.e. strm is NULL or the state was not initialized.
129  */
PREFIX(inflateBack)130 int32_t Z_EXPORT PREFIX(inflateBack)(PREFIX3(stream) *strm, in_func in, void *in_desc, out_func out, void *out_desc) {
131     struct inflate_state *state;
132     z_const unsigned char *next; /* next input */
133     unsigned char *put;          /* next output */
134     unsigned have, left;         /* available input and output */
135     uint32_t hold;               /* bit buffer */
136     unsigned bits;               /* bits in bit buffer */
137     unsigned copy;               /* number of stored or match bytes to copy */
138     unsigned char *from;         /* where to copy match bytes from */
139     code here;                   /* current decoding table entry */
140     code last;                   /* parent table entry */
141     unsigned len;                /* length to copy for repeats, bits to drop */
142     int32_t ret;                 /* return code */
143     static const uint16_t order[19] = /* permutation of code lengths */
144         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
145 
146     /* Check that the strm exists and that the state was initialized */
147     if (strm == NULL || strm->state == NULL)
148         return Z_STREAM_ERROR;
149     state = (struct inflate_state *)strm->state;
150 
151     /* Reset the state */
152     strm->msg = NULL;
153     state->mode = TYPE;
154     state->last = 0;
155     state->whave = 0;
156     next = strm->next_in;
157     have = next != NULL ? strm->avail_in : 0;
158     hold = 0;
159     bits = 0;
160     put = state->window;
161     left = state->wsize;
162 
163     /* Inflate until end of block marked as last */
164     for (;;)
165         switch (state->mode) {
166         case TYPE:
167             /* determine and dispatch block type */
168             if (state->last) {
169                 BYTEBITS();
170                 state->mode = DONE;
171                 break;
172             }
173             NEEDBITS(3);
174             state->last = BITS(1);
175             DROPBITS(1);
176             switch (BITS(2)) {
177             case 0:                             /* stored block */
178                 Tracev((stderr, "inflate:     stored block%s\n", state->last ? " (last)" : ""));
179                 state->mode = STORED;
180                 break;
181             case 1:                             /* fixed block */
182                 fixedtables(state);
183                 Tracev((stderr, "inflate:     fixed codes block%s\n", state->last ? " (last)" : ""));
184                 state->mode = LEN;              /* decode codes */
185                 break;
186             case 2:                             /* dynamic block */
187                 Tracev((stderr, "inflate:     dynamic codes block%s\n", state->last ? " (last)" : ""));
188                 state->mode = TABLE;
189                 break;
190             case 3:
191                 strm->msg = (char *)"invalid block type";
192                 state->mode = BAD;
193             }
194             DROPBITS(2);
195             break;
196 
197         case STORED:
198             /* get and verify stored block length */
199             BYTEBITS();                         /* go to byte boundary */
200             NEEDBITS(32);
201             if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
202                 strm->msg = (char *)"invalid stored block lengths";
203                 state->mode = BAD;
204                 break;
205             }
206             state->length = (uint16_t)hold;
207             Tracev((stderr, "inflate:       stored length %u\n", state->length));
208             INITBITS();
209 
210             /* copy stored block from input to output */
211             while (state->length != 0) {
212                 copy = state->length;
213                 PULL();
214                 ROOM();
215                 if (copy > have) copy = have;
216                 if (copy > left) copy = left;
217                 memcpy(put, next, copy);
218                 have -= copy;
219                 next += copy;
220                 left -= copy;
221                 put += copy;
222                 state->length -= copy;
223             }
224             Tracev((stderr, "inflate:       stored end\n"));
225             state->mode = TYPE;
226             break;
227 
228         case TABLE:
229             /* get dynamic table entries descriptor */
230             NEEDBITS(14);
231             state->nlen = BITS(5) + 257;
232             DROPBITS(5);
233             state->ndist = BITS(5) + 1;
234             DROPBITS(5);
235             state->ncode = BITS(4) + 4;
236             DROPBITS(4);
237 #ifndef PKZIP_BUG_WORKAROUND
238             if (state->nlen > 286 || state->ndist > 30) {
239                 strm->msg = (char *)"too many length or distance symbols";
240                 state->mode = BAD;
241                 break;
242             }
243 #endif
244             Tracev((stderr, "inflate:       table sizes ok\n"));
245             state->have = 0;
246 
247             /* get code length code lengths (not a typo) */
248             while (state->have < state->ncode) {
249                 NEEDBITS(3);
250                 state->lens[order[state->have++]] = (uint16_t)BITS(3);
251                 DROPBITS(3);
252             }
253             while (state->have < 19)
254                 state->lens[order[state->have++]] = 0;
255             state->next = state->codes;
256             state->lencode = (const code *)(state->next);
257             state->lenbits = 7;
258             ret = zng_inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work);
259             if (ret) {
260                 strm->msg = (char *)"invalid code lengths set";
261                 state->mode = BAD;
262                 break;
263             }
264             Tracev((stderr, "inflate:       code lengths ok\n"));
265             state->have = 0;
266 
267             /* get length and distance code code lengths */
268             while (state->have < state->nlen + state->ndist) {
269                 for (;;) {
270                     here = state->lencode[BITS(state->lenbits)];
271                     if (here.bits <= bits) break;
272                     PULLBYTE();
273                 }
274                 if (here.val < 16) {
275                     DROPBITS(here.bits);
276                     state->lens[state->have++] = here.val;
277                 } else {
278                     if (here.val == 16) {
279                         NEEDBITS(here.bits + 2);
280                         DROPBITS(here.bits);
281                         if (state->have == 0) {
282                             strm->msg = (char *)"invalid bit length repeat";
283                             state->mode = BAD;
284                             break;
285                         }
286                         len = state->lens[state->have - 1];
287                         copy = 3 + BITS(2);
288                         DROPBITS(2);
289                     } else if (here.val == 17) {
290                         NEEDBITS(here.bits + 3);
291                         DROPBITS(here.bits);
292                         len = 0;
293                         copy = 3 + BITS(3);
294                         DROPBITS(3);
295                     } else {
296                         NEEDBITS(here.bits + 7);
297                         DROPBITS(here.bits);
298                         len = 0;
299                         copy = 11 + BITS(7);
300                         DROPBITS(7);
301                     }
302                     if (state->have + copy > state->nlen + state->ndist) {
303                         strm->msg = (char *)"invalid bit length repeat";
304                         state->mode = BAD;
305                         break;
306                     }
307                     while (copy) {
308                         --copy;
309                         state->lens[state->have++] = (uint16_t)len;
310                     }
311                 }
312             }
313 
314             /* handle error breaks in while */
315             if (state->mode == BAD)
316                 break;
317 
318             /* check for end-of-block code (better have one) */
319             if (state->lens[256] == 0) {
320                 strm->msg = (char *)"invalid code -- missing end-of-block";
321                 state->mode = BAD;
322                 break;
323             }
324 
325             /* build code tables -- note: do not change the lenbits or distbits
326                values here (9 and 6) without reading the comments in inftrees.h
327                concerning the ENOUGH constants, which depend on those values */
328             state->next = state->codes;
329             state->lencode = (const code *)(state->next);
330             state->lenbits = 9;
331             ret = zng_inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work);
332             if (ret) {
333                 strm->msg = (char *)"invalid literal/lengths set";
334                 state->mode = BAD;
335                 break;
336             }
337             state->distcode = (const code *)(state->next);
338             state->distbits = 6;
339             ret = zng_inflate_table(DISTS, state->lens + state->nlen, state->ndist,
340                                 &(state->next), &(state->distbits), state->work);
341             if (ret) {
342                 strm->msg = (char *)"invalid distances set";
343                 state->mode = BAD;
344                 break;
345             }
346             Tracev((stderr, "inflate:       codes ok\n"));
347             state->mode = LEN;
348 
349         case LEN:
350             /* use inflate_fast() if we have enough input and output */
351             if (have >= INFLATE_FAST_MIN_HAVE &&
352                 left >= INFLATE_FAST_MIN_LEFT) {
353                 RESTORE();
354                 if (state->whave < state->wsize)
355                     state->whave = state->wsize - left;
356                 zng_inflate_fast(strm, state->wsize);
357                 LOAD();
358                 break;
359             }
360 
361             /* get a literal, length, or end-of-block code */
362             for (;;) {
363                 here = state->lencode[BITS(state->lenbits)];
364                 if (here.bits <= bits)
365                     break;
366                 PULLBYTE();
367             }
368             if (here.op && (here.op & 0xf0) == 0) {
369                 last = here;
370                 for (;;) {
371                     here = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)];
372                     if ((unsigned)last.bits + (unsigned)here.bits <= bits)
373                         break;
374                     PULLBYTE();
375                 }
376                 DROPBITS(last.bits);
377             }
378             DROPBITS(here.bits);
379             state->length = here.val;
380 
381             /* process literal */
382             if ((int)(here.op) == 0) {
383                 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
384                         "inflate:         literal '%c'\n" :
385                         "inflate:         literal 0x%02x\n", here.val));
386                 ROOM();
387                 *put++ = (unsigned char)(state->length);
388                 left--;
389                 state->mode = LEN;
390                 break;
391             }
392 
393             /* process end of block */
394             if (here.op & 32) {
395                 Tracevv((stderr, "inflate:         end of block\n"));
396                 state->mode = TYPE;
397                 break;
398             }
399 
400             /* invalid code */
401             if (here.op & 64) {
402                 strm->msg = (char *)"invalid literal/length code";
403                 state->mode = BAD;
404                 break;
405             }
406 
407             /* length code -- get extra bits, if any */
408             state->extra = (here.op & 15);
409             if (state->extra) {
410                 NEEDBITS(state->extra);
411                 state->length += BITS(state->extra);
412                 DROPBITS(state->extra);
413             }
414             Tracevv((stderr, "inflate:         length %u\n", state->length));
415 
416             /* get distance code */
417             for (;;) {
418                 here = state->distcode[BITS(state->distbits)];
419                 if (here.bits <= bits)
420                     break;
421                 PULLBYTE();
422             }
423             if ((here.op & 0xf0) == 0) {
424                 last = here;
425                 for (;;) {
426                     here = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)];
427                     if ((unsigned)last.bits + (unsigned)here.bits <= bits)
428                         break;
429                     PULLBYTE();
430                 }
431                 DROPBITS(last.bits);
432             }
433             DROPBITS(here.bits);
434             if (here.op & 64) {
435                 strm->msg = (char *)"invalid distance code";
436                 state->mode = BAD;
437                 break;
438             }
439             state->offset = here.val;
440             state->extra = (here.op & 15);
441 
442             /* get distance extra bits, if any */
443             if (state->extra) {
444                 NEEDBITS(state->extra);
445                 state->offset += BITS(state->extra);
446                 DROPBITS(state->extra);
447             }
448 #ifdef INFLATE_STRICT
449             if (state->offset > state->wsize - (state->whave < state->wsize ? left : 0)) {
450                 strm->msg = (char *)"invalid distance too far back";
451                 state->mode = BAD;
452                 break;
453             }
454 #endif
455             Tracevv((stderr, "inflate:         distance %u\n", state->offset));
456 
457             /* copy match from window to output */
458             do {
459                 ROOM();
460                 copy = state->wsize - state->offset;
461                 if (copy < left) {
462                     from = put + copy;
463                     copy = left - copy;
464                 } else {
465                     from = put - state->offset;
466                     copy = left;
467                 }
468                 if (copy > state->length)
469                     copy = state->length;
470                 state->length -= copy;
471                 left -= copy;
472                 do {
473                     *put++ = *from++;
474                 } while (--copy);
475             } while (state->length != 0);
476             break;
477 
478         case DONE:
479             /* inflate stream terminated properly -- write leftover output */
480             ret = Z_STREAM_END;
481             if (left < state->wsize) {
482                 if (out(out_desc, state->window, state->wsize - left))
483                     ret = Z_BUF_ERROR;
484             }
485             goto inf_leave;
486 
487         case BAD:
488             ret = Z_DATA_ERROR;
489             goto inf_leave;
490 
491         default:                /* can't happen, but makes compilers happy */
492             ret = Z_STREAM_ERROR;
493             goto inf_leave;
494         }
495 
496     /* Return unused input */
497   inf_leave:
498     strm->next_in = next;
499     strm->avail_in = have;
500     return ret;
501 }
502 
PREFIX(inflateBackEnd)503 int32_t Z_EXPORT PREFIX(inflateBackEnd)(PREFIX3(stream) *strm) {
504     if (strm == NULL || strm->state == NULL || strm->zfree == NULL)
505         return Z_STREAM_ERROR;
506     ZFREE(strm, strm->state);
507     strm->state = NULL;
508     Tracev((stderr, "inflate: end\n"));
509     return Z_OK;
510 }
511