xref: /openbsd-src/sys/lib/libz/infback.c (revision fb9b015228f7ecb1179e6f095135f306e545d46d)
1a79de952Smillert /* infback.c -- inflate using a call-back interface
2a6530658Stb  * Copyright (C) 1995-2022 Mark Adler
3a79de952Smillert  * For conditions of distribution and use, see copyright notice in zlib.h
4a79de952Smillert  */
5a79de952Smillert 
6a79de952Smillert /*
7a79de952Smillert    This code is largely copied from inflate.c.  Normally either infback.o or
8a79de952Smillert    inflate.o would be linked into an application--not both.  The interface
9a79de952Smillert    with inffast.c is retained so that optimized assembler-coded versions of
10a79de952Smillert    inflate_fast() can be used with either inflate.c or infback.c.
11a79de952Smillert  */
12a79de952Smillert 
13a79de952Smillert #include "zutil.h"
14a79de952Smillert #include "inftrees.h"
15a79de952Smillert #include "inflate.h"
16a79de952Smillert #include "inffast.h"
17a79de952Smillert 
18a79de952Smillert /*
19a79de952Smillert    strm provides memory allocation functions in zalloc and zfree, or
20a79de952Smillert    Z_NULL to use the library memory allocation functions.
21a79de952Smillert 
22a79de952Smillert    windowBits is in the range 8..15, and window is a user-supplied
23a79de952Smillert    window and output buffer that is 2**windowBits bytes.
24a79de952Smillert  */
inflateBackInit_(z_streamp strm,int windowBits,unsigned char FAR * window,const char * version,int stream_size)25cfac609cStb int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits,
26cfac609cStb                              unsigned char FAR *window, const char *version,
27cfac609cStb                              int stream_size) {
28a79de952Smillert     struct inflate_state FAR *state;
29a79de952Smillert 
30a79de952Smillert     if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
31a79de952Smillert         stream_size != (int)(sizeof(z_stream)))
32a79de952Smillert         return Z_VERSION_ERROR;
33a79de952Smillert     if (strm == Z_NULL || window == Z_NULL ||
34a79de952Smillert         windowBits < 8 || windowBits > 15)
35a79de952Smillert         return Z_STREAM_ERROR;
36a79de952Smillert     strm->msg = Z_NULL;                 /* in case we return an error */
37a79de952Smillert     if (strm->zalloc == (alloc_func)0) {
3836f395ceStb #ifdef Z_SOLO
3936f395ceStb         return Z_STREAM_ERROR;
4036f395ceStb #else
41a79de952Smillert         strm->zalloc = zcalloc;
42a79de952Smillert         strm->opaque = (voidpf)0;
4336f395ceStb #endif
44a79de952Smillert     }
4536f395ceStb     if (strm->zfree == (free_func)0)
4636f395ceStb #ifdef Z_SOLO
4736f395ceStb         return Z_STREAM_ERROR;
4836f395ceStb #else
4936f395ceStb     strm->zfree = zcfree;
5036f395ceStb #endif
51a79de952Smillert     state = (struct inflate_state FAR *)ZALLOC(strm, 1,
52a79de952Smillert                                                sizeof(struct inflate_state));
53a79de952Smillert     if (state == Z_NULL) return Z_MEM_ERROR;
54a79de952Smillert     Tracev((stderr, "inflate: allocated\n"));
55d76b9bfaSmillert     strm->state = (struct internal_state FAR *)state;
56d76b9bfaSmillert     state->dmax = 32768U;
5736f395ceStb     state->wbits = (uInt)windowBits;
58a79de952Smillert     state->wsize = 1U << windowBits;
59a79de952Smillert     state->window = window;
6036f395ceStb     state->wnext = 0;
61a79de952Smillert     state->whave = 0;
62ddf65acdStb     state->sane = 1;
63a79de952Smillert     return Z_OK;
64a79de952Smillert }
65a79de952Smillert 
66a79de952Smillert /*
67a79de952Smillert    Return state with length and distance decoding tables and index sizes set to
68a79de952Smillert    fixed code decoding.  Normally this returns fixed tables from inffixed.h.
69a79de952Smillert    If BUILDFIXED is defined, then instead this routine builds the tables the
70a79de952Smillert    first time it's called, and returns those tables the first time and
71a79de952Smillert    thereafter.  This reduces the size of the code by about 2K bytes, in
72a79de952Smillert    exchange for a little execution time.  However, BUILDFIXED should not be
73a79de952Smillert    used for threaded applications, since the rewriting of the tables and virgin
74a79de952Smillert    may not be thread-safe.
75a79de952Smillert  */
fixedtables(struct inflate_state FAR * state)76cfac609cStb local void fixedtables(struct inflate_state FAR *state) {
77a79de952Smillert #ifdef BUILDFIXED
78a79de952Smillert     static int virgin = 1;
79a79de952Smillert     static code *lenfix, *distfix;
80a79de952Smillert     static code fixed[544];
81a79de952Smillert 
82a79de952Smillert     /* build fixed huffman tables if first call (may not be thread safe) */
83a79de952Smillert     if (virgin) {
84a79de952Smillert         unsigned sym, bits;
85a79de952Smillert         static code *next;
86a79de952Smillert 
87a79de952Smillert         /* literal/length table */
88a79de952Smillert         sym = 0;
89a79de952Smillert         while (sym < 144) state->lens[sym++] = 8;
90a79de952Smillert         while (sym < 256) state->lens[sym++] = 9;
91a79de952Smillert         while (sym < 280) state->lens[sym++] = 7;
92a79de952Smillert         while (sym < 288) state->lens[sym++] = 8;
93a79de952Smillert         next = fixed;
94a79de952Smillert         lenfix = next;
95a79de952Smillert         bits = 9;
96a79de952Smillert         inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
97a79de952Smillert 
98a79de952Smillert         /* distance table */
99a79de952Smillert         sym = 0;
100a79de952Smillert         while (sym < 32) state->lens[sym++] = 5;
101a79de952Smillert         distfix = next;
102a79de952Smillert         bits = 5;
103a79de952Smillert         inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
104a79de952Smillert 
105a79de952Smillert         /* do this just once */
106a79de952Smillert         virgin = 0;
107a79de952Smillert     }
108a79de952Smillert #else /* !BUILDFIXED */
109a79de952Smillert #   include "inffixed.h"
110a79de952Smillert #endif /* BUILDFIXED */
111a79de952Smillert     state->lencode = lenfix;
112a79de952Smillert     state->lenbits = 9;
113a79de952Smillert     state->distcode = distfix;
114a79de952Smillert     state->distbits = 5;
115a79de952Smillert }
116a79de952Smillert 
117a79de952Smillert /* Macros for inflateBack(): */
118a79de952Smillert 
119a79de952Smillert /* Load returned state from inflate_fast() */
120a79de952Smillert #define LOAD() \
121a79de952Smillert     do { \
122a79de952Smillert         put = strm->next_out; \
123a79de952Smillert         left = strm->avail_out; \
124a79de952Smillert         next = strm->next_in; \
125a79de952Smillert         have = strm->avail_in; \
126a79de952Smillert         hold = state->hold; \
127a79de952Smillert         bits = state->bits; \
128a79de952Smillert     } while (0)
129a79de952Smillert 
130a79de952Smillert /* Set state from registers for inflate_fast() */
131a79de952Smillert #define RESTORE() \
132a79de952Smillert     do { \
133a79de952Smillert         strm->next_out = put; \
134a79de952Smillert         strm->avail_out = left; \
135a79de952Smillert         strm->next_in = next; \
136a79de952Smillert         strm->avail_in = have; \
137a79de952Smillert         state->hold = hold; \
138a79de952Smillert         state->bits = bits; \
139a79de952Smillert     } while (0)
140a79de952Smillert 
141a79de952Smillert /* Clear the input bit accumulator */
142a79de952Smillert #define INITBITS() \
143a79de952Smillert     do { \
144a79de952Smillert         hold = 0; \
145a79de952Smillert         bits = 0; \
146a79de952Smillert     } while (0)
147a79de952Smillert 
148a79de952Smillert /* Assure that some input is available.  If input is requested, but denied,
149a79de952Smillert    then return a Z_BUF_ERROR from inflateBack(). */
150a79de952Smillert #define PULL() \
151a79de952Smillert     do { \
152a79de952Smillert         if (have == 0) { \
153a79de952Smillert             have = in(in_desc, &next); \
154a79de952Smillert             if (have == 0) { \
155a79de952Smillert                 next = Z_NULL; \
156a79de952Smillert                 ret = Z_BUF_ERROR; \
157a79de952Smillert                 goto inf_leave; \
158a79de952Smillert             } \
159a79de952Smillert         } \
160a79de952Smillert     } while (0)
161a79de952Smillert 
162a79de952Smillert /* Get a byte of input into the bit accumulator, or return from inflateBack()
163a79de952Smillert    with an error if there is no input available. */
164a79de952Smillert #define PULLBYTE() \
165a79de952Smillert     do { \
166a79de952Smillert         PULL(); \
167a79de952Smillert         have--; \
168a79de952Smillert         hold += (unsigned long)(*next++) << bits; \
169a79de952Smillert         bits += 8; \
170a79de952Smillert     } while (0)
171a79de952Smillert 
172a79de952Smillert /* Assure that there are at least n bits in the bit accumulator.  If there is
173a79de952Smillert    not enough available input to do that, then return from inflateBack() with
174a79de952Smillert    an error. */
175a79de952Smillert #define NEEDBITS(n) \
176a79de952Smillert     do { \
177a79de952Smillert         while (bits < (unsigned)(n)) \
178a79de952Smillert             PULLBYTE(); \
179a79de952Smillert     } while (0)
180a79de952Smillert 
181a79de952Smillert /* Return the low n bits of the bit accumulator (n < 16) */
182a79de952Smillert #define BITS(n) \
183a79de952Smillert     ((unsigned)hold & ((1U << (n)) - 1))
184a79de952Smillert 
185a79de952Smillert /* Remove n bits from the bit accumulator */
186a79de952Smillert #define DROPBITS(n) \
187a79de952Smillert     do { \
188a79de952Smillert         hold >>= (n); \
189a79de952Smillert         bits -= (unsigned)(n); \
190a79de952Smillert     } while (0)
191a79de952Smillert 
192a79de952Smillert /* Remove zero to seven bits as needed to go to a byte boundary */
193a79de952Smillert #define BYTEBITS() \
194a79de952Smillert     do { \
195a79de952Smillert         hold >>= bits & 7; \
196a79de952Smillert         bits -= bits & 7; \
197a79de952Smillert     } while (0)
198a79de952Smillert 
199a79de952Smillert /* Assure that some output space is available, by writing out the window
200a79de952Smillert    if it's full.  If the write fails, return from inflateBack() with a
201a79de952Smillert    Z_BUF_ERROR. */
202a79de952Smillert #define ROOM() \
203a79de952Smillert     do { \
204a79de952Smillert         if (left == 0) { \
205a79de952Smillert             put = state->window; \
206a79de952Smillert             left = state->wsize; \
207a79de952Smillert             state->whave = left; \
208a79de952Smillert             if (out(out_desc, put, left)) { \
209a79de952Smillert                 ret = Z_BUF_ERROR; \
210a79de952Smillert                 goto inf_leave; \
211a79de952Smillert             } \
212a79de952Smillert         } \
213a79de952Smillert     } while (0)
214a79de952Smillert 
215a79de952Smillert /*
216a79de952Smillert    strm provides the memory allocation functions and window buffer on input,
217a79de952Smillert    and provides information on the unused input on return.  For Z_DATA_ERROR
218a79de952Smillert    returns, strm will also provide an error message.
219a79de952Smillert 
220a79de952Smillert    in() and out() are the call-back input and output functions.  When
221a79de952Smillert    inflateBack() needs more input, it calls in().  When inflateBack() has
222a79de952Smillert    filled the window with output, or when it completes with data in the
223a79de952Smillert    window, it calls out() to write out the data.  The application must not
224a79de952Smillert    change the provided input until in() is called again or inflateBack()
225a79de952Smillert    returns.  The application must not change the window/output buffer until
226a79de952Smillert    inflateBack() returns.
227a79de952Smillert 
228a79de952Smillert    in() and out() are called with a descriptor parameter provided in the
229a79de952Smillert    inflateBack() call.  This parameter can be a structure that provides the
230a79de952Smillert    information required to do the read or write, as well as accumulated
231a79de952Smillert    information on the input and output such as totals and check values.
232a79de952Smillert 
233a79de952Smillert    in() should return zero on failure.  out() should return non-zero on
234a79de952Smillert    failure.  If either in() or out() fails, than inflateBack() returns a
235a79de952Smillert    Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
236a79de952Smillert    was in() or out() that caused in the error.  Otherwise,  inflateBack()
237a79de952Smillert    returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
238a79de952Smillert    error, or Z_MEM_ERROR if it could not allocate memory for the state.
239a79de952Smillert    inflateBack() can also return Z_STREAM_ERROR if the input parameters
240a79de952Smillert    are not correct, i.e. strm is Z_NULL or the state was not initialized.
241a79de952Smillert  */
inflateBack(z_streamp strm,in_func in,void FAR * in_desc,out_func out,void FAR * out_desc)242cfac609cStb int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc,
243cfac609cStb                         out_func out, void FAR *out_desc) {
244a79de952Smillert     struct inflate_state FAR *state;
245efa1b761Sjca     z_const unsigned char FAR *next;    /* next input */
246a79de952Smillert     unsigned char FAR *put;     /* next output */
247a79de952Smillert     unsigned have, left;        /* available input and output */
248a79de952Smillert     unsigned long hold;         /* bit buffer */
249a79de952Smillert     unsigned bits;              /* bits in bit buffer */
250a79de952Smillert     unsigned copy;              /* number of stored or match bytes to copy */
251a79de952Smillert     unsigned char FAR *from;    /* where to copy match bytes from */
25236f395ceStb     code here;                  /* current decoding table entry */
253a79de952Smillert     code last;                  /* parent table entry */
254a79de952Smillert     unsigned len;               /* length to copy for repeats, bits to drop */
255a79de952Smillert     int ret;                    /* return code */
256a79de952Smillert     static const unsigned short order[19] = /* permutation of code lengths */
257a79de952Smillert         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
258a79de952Smillert 
259a79de952Smillert     /* Check that the strm exists and that the state was initialized */
260a79de952Smillert     if (strm == Z_NULL || strm->state == Z_NULL)
261a79de952Smillert         return Z_STREAM_ERROR;
262a79de952Smillert     state = (struct inflate_state FAR *)strm->state;
263a79de952Smillert 
264a79de952Smillert     /* Reset the state */
265a79de952Smillert     strm->msg = Z_NULL;
266a79de952Smillert     state->mode = TYPE;
267a79de952Smillert     state->last = 0;
268a79de952Smillert     state->whave = 0;
269a79de952Smillert     next = strm->next_in;
270a79de952Smillert     have = next != Z_NULL ? strm->avail_in : 0;
271a79de952Smillert     hold = 0;
272a79de952Smillert     bits = 0;
273a79de952Smillert     put = state->window;
274a79de952Smillert     left = state->wsize;
275a79de952Smillert 
276a79de952Smillert     /* Inflate until end of block marked as last */
277a79de952Smillert     for (;;)
278a79de952Smillert         switch (state->mode) {
279a79de952Smillert         case TYPE:
280a79de952Smillert             /* determine and dispatch block type */
281a79de952Smillert             if (state->last) {
282a79de952Smillert                 BYTEBITS();
283a79de952Smillert                 state->mode = DONE;
284a79de952Smillert                 break;
285a79de952Smillert             }
286a79de952Smillert             NEEDBITS(3);
287a79de952Smillert             state->last = BITS(1);
288a79de952Smillert             DROPBITS(1);
289a79de952Smillert             switch (BITS(2)) {
290a79de952Smillert             case 0:                             /* stored block */
291a79de952Smillert                 Tracev((stderr, "inflate:     stored block%s\n",
292a79de952Smillert                         state->last ? " (last)" : ""));
293a79de952Smillert                 state->mode = STORED;
294a79de952Smillert                 break;
295a79de952Smillert             case 1:                             /* fixed block */
296a79de952Smillert                 fixedtables(state);
297a79de952Smillert                 Tracev((stderr, "inflate:     fixed codes block%s\n",
298a79de952Smillert                         state->last ? " (last)" : ""));
299a79de952Smillert                 state->mode = LEN;              /* decode codes */
300a79de952Smillert                 break;
301a79de952Smillert             case 2:                             /* dynamic block */
302a79de952Smillert                 Tracev((stderr, "inflate:     dynamic codes block%s\n",
303a79de952Smillert                         state->last ? " (last)" : ""));
304a79de952Smillert                 state->mode = TABLE;
305a79de952Smillert                 break;
306a79de952Smillert             case 3:
3070ede0c43Smillert #ifdef SMALL
308*fb9b0152Stb                 strm->msg = (z_const char *)"error";
3090ede0c43Smillert #else
310*fb9b0152Stb                 strm->msg = (z_const char *)"invalid block type";
3110ede0c43Smillert #endif
312a79de952Smillert                 state->mode = BAD;
313a79de952Smillert             }
314a79de952Smillert             DROPBITS(2);
315a79de952Smillert             break;
316a79de952Smillert 
317a79de952Smillert         case STORED:
318a79de952Smillert             /* get and verify stored block length */
319a79de952Smillert             BYTEBITS();                         /* go to byte boundary */
320a79de952Smillert             NEEDBITS(32);
321a79de952Smillert             if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
3220ede0c43Smillert #ifdef SMALL
323*fb9b0152Stb                 strm->msg = (z_const char *)"error";
3240ede0c43Smillert #else
325*fb9b0152Stb                 strm->msg = (z_const char *)"invalid stored block lengths";
3260ede0c43Smillert #endif
327a79de952Smillert                 state->mode = BAD;
328a79de952Smillert                 break;
329a79de952Smillert             }
330a79de952Smillert             state->length = (unsigned)hold & 0xffff;
331a79de952Smillert             Tracev((stderr, "inflate:       stored length %u\n",
332a79de952Smillert                     state->length));
333a79de952Smillert             INITBITS();
334a79de952Smillert 
335a79de952Smillert             /* copy stored block from input to output */
336a79de952Smillert             while (state->length != 0) {
337a79de952Smillert                 copy = state->length;
338a79de952Smillert                 PULL();
339a79de952Smillert                 ROOM();
340a79de952Smillert                 if (copy > have) copy = have;
341a79de952Smillert                 if (copy > left) copy = left;
342a79de952Smillert                 zmemcpy(put, next, copy);
343a79de952Smillert                 have -= copy;
344a79de952Smillert                 next += copy;
345a79de952Smillert                 left -= copy;
346a79de952Smillert                 put += copy;
347a79de952Smillert                 state->length -= copy;
348a79de952Smillert             }
349a79de952Smillert             Tracev((stderr, "inflate:       stored end\n"));
350a79de952Smillert             state->mode = TYPE;
351a79de952Smillert             break;
352a79de952Smillert 
353a79de952Smillert         case TABLE:
354a79de952Smillert             /* get dynamic table entries descriptor */
355a79de952Smillert             NEEDBITS(14);
356a79de952Smillert             state->nlen = BITS(5) + 257;
357a79de952Smillert             DROPBITS(5);
358a79de952Smillert             state->ndist = BITS(5) + 1;
359a79de952Smillert             DROPBITS(5);
360a79de952Smillert             state->ncode = BITS(4) + 4;
361a79de952Smillert             DROPBITS(4);
362a79de952Smillert #ifndef PKZIP_BUG_WORKAROUND
363a79de952Smillert             if (state->nlen > 286 || state->ndist > 30) {
3640ede0c43Smillert #ifdef SMALL
365*fb9b0152Stb                 strm->msg = (z_const char *)"error";
3660ede0c43Smillert #else
367*fb9b0152Stb                 strm->msg = (z_const char *)"too many length or distance symbols";
3680ede0c43Smillert #endif
369a79de952Smillert                 state->mode = BAD;
370a79de952Smillert                 break;
371a79de952Smillert             }
372a79de952Smillert #endif
373a79de952Smillert             Tracev((stderr, "inflate:       table sizes ok\n"));
374a79de952Smillert 
375a79de952Smillert             /* get code length code lengths (not a typo) */
376a79de952Smillert             state->have = 0;
377a79de952Smillert             while (state->have < state->ncode) {
378a79de952Smillert                 NEEDBITS(3);
379a79de952Smillert                 state->lens[order[state->have++]] = (unsigned short)BITS(3);
380a79de952Smillert                 DROPBITS(3);
381a79de952Smillert             }
382a79de952Smillert             while (state->have < 19)
383a79de952Smillert                 state->lens[order[state->have++]] = 0;
384a79de952Smillert             state->next = state->codes;
385a79de952Smillert             state->lencode = (code const FAR *)(state->next);
386a79de952Smillert             state->lenbits = 7;
387a79de952Smillert             ret = inflate_table(CODES, state->lens, 19, &(state->next),
388a79de952Smillert                                 &(state->lenbits), state->work);
389a79de952Smillert             if (ret) {
39036f395ceStb #ifdef SMALL
391*fb9b0152Stb                 strm->msg = (z_const char *)"error";
39236f395ceStb #else
393*fb9b0152Stb                 strm->msg = (z_const char *)"invalid code lengths set";
39436f395ceStb #endif
395a79de952Smillert                 state->mode = BAD;
396a79de952Smillert                 break;
397a79de952Smillert             }
398a79de952Smillert             Tracev((stderr, "inflate:       code lengths ok\n"));
399a79de952Smillert 
400a79de952Smillert             /* get length and distance code code lengths */
401a79de952Smillert             state->have = 0;
402a79de952Smillert             while (state->have < state->nlen + state->ndist) {
403a79de952Smillert                 for (;;) {
40436f395ceStb                     here = state->lencode[BITS(state->lenbits)];
40536f395ceStb                     if ((unsigned)(here.bits) <= bits) break;
406a79de952Smillert                     PULLBYTE();
407a79de952Smillert                 }
40836f395ceStb                 if (here.val < 16) {
40936f395ceStb                     DROPBITS(here.bits);
41036f395ceStb                     state->lens[state->have++] = here.val;
411a79de952Smillert                 }
412a79de952Smillert                 else {
41336f395ceStb                     if (here.val == 16) {
41436f395ceStb                         NEEDBITS(here.bits + 2);
41536f395ceStb                         DROPBITS(here.bits);
416a79de952Smillert                         if (state->have == 0) {
41736f395ceStb #ifdef SMALL
418*fb9b0152Stb                             strm->msg = (z_const char *)"error";
41936f395ceStb #else
420*fb9b0152Stb                             strm->msg = (z_const char *)"invalid bit length repeat";
42136f395ceStb #endif
422a79de952Smillert                             state->mode = BAD;
423a79de952Smillert                             break;
424a79de952Smillert                         }
425a79de952Smillert                         len = (unsigned)(state->lens[state->have - 1]);
426a79de952Smillert                         copy = 3 + BITS(2);
427a79de952Smillert                         DROPBITS(2);
428a79de952Smillert                     }
42936f395ceStb                     else if (here.val == 17) {
43036f395ceStb                         NEEDBITS(here.bits + 3);
43136f395ceStb                         DROPBITS(here.bits);
432a79de952Smillert                         len = 0;
433a79de952Smillert                         copy = 3 + BITS(3);
434a79de952Smillert                         DROPBITS(3);
435a79de952Smillert                     }
436a79de952Smillert                     else {
43736f395ceStb                         NEEDBITS(here.bits + 7);
43836f395ceStb                         DROPBITS(here.bits);
439a79de952Smillert                         len = 0;
440a79de952Smillert                         copy = 11 + BITS(7);
441a79de952Smillert                         DROPBITS(7);
442a79de952Smillert                     }
443a79de952Smillert                     if (state->have + copy > state->nlen + state->ndist) {
44436f395ceStb #ifdef SMALL
445*fb9b0152Stb                         strm->msg = (z_const char *)"error";
44636f395ceStb #else
447*fb9b0152Stb                         strm->msg = (z_const char *)"invalid bit length repeat";
44836f395ceStb #endif
449a79de952Smillert                         state->mode = BAD;
450a79de952Smillert                         break;
451a79de952Smillert                     }
452a79de952Smillert                     while (copy--)
453a79de952Smillert                         state->lens[state->have++] = (unsigned short)len;
454a79de952Smillert                 }
455a79de952Smillert             }
456a79de952Smillert 
457dec6a01cSdjm             /* handle error breaks in while */
458dec6a01cSdjm             if (state->mode == BAD) break;
459a29b1a55Sotto 
46036f395ceStb             /* check for end-of-block code (better have one) */
46136f395ceStb             if (state->lens[256] == 0) {
46236f395ceStb #ifdef SMALL
463*fb9b0152Stb                 strm->msg = (z_const char *)"error";
46436f395ceStb #else
465*fb9b0152Stb                 strm->msg = (z_const char *)"invalid code -- missing end-of-block";
46636f395ceStb #endif
46736f395ceStb                 state->mode = BAD;
46836f395ceStb                 break;
46936f395ceStb             }
47036f395ceStb 
47136f395ceStb             /* build code tables -- note: do not change the lenbits or distbits
47236f395ceStb                values here (9 and 6) without reading the comments in inftrees.h
47336f395ceStb                concerning the ENOUGH constants, which depend on those values */
474a79de952Smillert             state->next = state->codes;
475a79de952Smillert             state->lencode = (code const FAR *)(state->next);
476a79de952Smillert             state->lenbits = 9;
477a79de952Smillert             ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
478a79de952Smillert                                 &(state->lenbits), state->work);
479a79de952Smillert             if (ret) {
48036f395ceStb #ifdef SMALL
481*fb9b0152Stb                 strm->msg = (z_const char *)"error";
48236f395ceStb #else
483*fb9b0152Stb                 strm->msg = (z_const char *)"invalid literal/lengths set";
48436f395ceStb #endif
485a79de952Smillert                 state->mode = BAD;
486a79de952Smillert                 break;
487a79de952Smillert             }
488a79de952Smillert             state->distcode = (code const FAR *)(state->next);
489a79de952Smillert             state->distbits = 6;
490a79de952Smillert             ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
491a79de952Smillert                             &(state->next), &(state->distbits), state->work);
492a79de952Smillert             if (ret) {
49336f395ceStb #ifdef SMALL
494*fb9b0152Stb                 strm->msg = (z_const char *)"error";
49536f395ceStb #else
496*fb9b0152Stb                 strm->msg = (z_const char *)"invalid distances set";
49736f395ceStb #endif
498a79de952Smillert                 state->mode = BAD;
499a79de952Smillert                 break;
500a79de952Smillert             }
501a79de952Smillert             Tracev((stderr, "inflate:       codes ok\n"));
502a79de952Smillert             state->mode = LEN;
503a6530658Stb                 /* fallthrough */
504a79de952Smillert 
505a79de952Smillert         case LEN:
5060ede0c43Smillert #ifndef SLOW
507a79de952Smillert             /* use inflate_fast() if we have enough input and output */
508a79de952Smillert             if (have >= 6 && left >= 258) {
509a79de952Smillert                 RESTORE();
510a79de952Smillert                 if (state->whave < state->wsize)
511a79de952Smillert                     state->whave = state->wsize - left;
512a79de952Smillert                 inflate_fast(strm, state->wsize);
513a79de952Smillert                 LOAD();
514a79de952Smillert                 break;
515a79de952Smillert             }
5160ede0c43Smillert #endif
517a79de952Smillert 
518a79de952Smillert             /* get a literal, length, or end-of-block code */
519a79de952Smillert             for (;;) {
52036f395ceStb                 here = state->lencode[BITS(state->lenbits)];
52136f395ceStb                 if ((unsigned)(here.bits) <= bits) break;
522a79de952Smillert                 PULLBYTE();
523a79de952Smillert             }
52436f395ceStb             if (here.op && (here.op & 0xf0) == 0) {
52536f395ceStb                 last = here;
526a79de952Smillert                 for (;;) {
52736f395ceStb                     here = state->lencode[last.val +
528a79de952Smillert                             (BITS(last.bits + last.op) >> last.bits)];
52936f395ceStb                     if ((unsigned)(last.bits + here.bits) <= bits) break;
530a79de952Smillert                     PULLBYTE();
531a79de952Smillert                 }
532a79de952Smillert                 DROPBITS(last.bits);
533a79de952Smillert             }
53436f395ceStb             DROPBITS(here.bits);
53536f395ceStb             state->length = (unsigned)here.val;
536a79de952Smillert 
537a79de952Smillert             /* process literal */
53836f395ceStb             if (here.op == 0) {
53936f395ceStb                 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
540a79de952Smillert                         "inflate:         literal '%c'\n" :
54136f395ceStb                         "inflate:         literal 0x%02x\n", here.val));
542a79de952Smillert                 ROOM();
543a79de952Smillert                 *put++ = (unsigned char)(state->length);
544a79de952Smillert                 left--;
545a79de952Smillert                 state->mode = LEN;
546a79de952Smillert                 break;
547a79de952Smillert             }
548a79de952Smillert 
549a79de952Smillert             /* process end of block */
55036f395ceStb             if (here.op & 32) {
551a79de952Smillert                 Tracevv((stderr, "inflate:         end of block\n"));
552a79de952Smillert                 state->mode = TYPE;
553a79de952Smillert                 break;
554a79de952Smillert             }
555a79de952Smillert 
556a79de952Smillert             /* invalid code */
55736f395ceStb             if (here.op & 64) {
55836f395ceStb #ifdef SMALL
559*fb9b0152Stb                 strm->msg = (z_const char *)"error";
56036f395ceStb #else
561*fb9b0152Stb                 strm->msg = (z_const char *)"invalid literal/length code";
56236f395ceStb #endif
563a79de952Smillert                 state->mode = BAD;
564a79de952Smillert                 break;
565a79de952Smillert             }
566a79de952Smillert 
567a79de952Smillert             /* length code -- get extra bits, if any */
56836f395ceStb             state->extra = (unsigned)(here.op) & 15;
569a79de952Smillert             if (state->extra != 0) {
570a79de952Smillert                 NEEDBITS(state->extra);
571a79de952Smillert                 state->length += BITS(state->extra);
572a79de952Smillert                 DROPBITS(state->extra);
573a79de952Smillert             }
574a79de952Smillert             Tracevv((stderr, "inflate:         length %u\n", state->length));
575a79de952Smillert 
576a79de952Smillert             /* get distance code */
577a79de952Smillert             for (;;) {
57836f395ceStb                 here = state->distcode[BITS(state->distbits)];
57936f395ceStb                 if ((unsigned)(here.bits) <= bits) break;
580a79de952Smillert                 PULLBYTE();
581a79de952Smillert             }
58236f395ceStb             if ((here.op & 0xf0) == 0) {
58336f395ceStb                 last = here;
584a79de952Smillert                 for (;;) {
58536f395ceStb                     here = state->distcode[last.val +
586a79de952Smillert                             (BITS(last.bits + last.op) >> last.bits)];
58736f395ceStb                     if ((unsigned)(last.bits + here.bits) <= bits) break;
588a79de952Smillert                     PULLBYTE();
589a79de952Smillert                 }
590a79de952Smillert                 DROPBITS(last.bits);
591a79de952Smillert             }
59236f395ceStb             DROPBITS(here.bits);
59336f395ceStb             if (here.op & 64) {
59436f395ceStb #ifdef SMALL
595*fb9b0152Stb                 strm->msg = (z_const char *)"error";
59636f395ceStb #else
597*fb9b0152Stb                 strm->msg = (z_const char *)"invalid distance code";
59836f395ceStb #endif
599a79de952Smillert                 state->mode = BAD;
600a79de952Smillert                 break;
601a79de952Smillert             }
60236f395ceStb             state->offset = (unsigned)here.val;
603a79de952Smillert 
604a79de952Smillert             /* get distance extra bits, if any */
60536f395ceStb             state->extra = (unsigned)(here.op) & 15;
606a79de952Smillert             if (state->extra != 0) {
607a79de952Smillert                 NEEDBITS(state->extra);
608a79de952Smillert                 state->offset += BITS(state->extra);
609a79de952Smillert                 DROPBITS(state->extra);
610a79de952Smillert             }
611a79de952Smillert             if (state->offset > state->wsize - (state->whave < state->wsize ?
612a79de952Smillert                                                 left : 0)) {
61336f395ceStb #ifdef SMALL
614*fb9b0152Stb                 strm->msg = (z_const char *)"error";
61536f395ceStb #else
616*fb9b0152Stb                 strm->msg = (z_const char *)"invalid distance too far back";
61736f395ceStb #endif
618a79de952Smillert                 state->mode = BAD;
619a79de952Smillert                 break;
620a79de952Smillert             }
621a79de952Smillert             Tracevv((stderr, "inflate:         distance %u\n", state->offset));
622a79de952Smillert 
623a79de952Smillert             /* copy match from window to output */
624a79de952Smillert             do {
625a79de952Smillert                 ROOM();
626a79de952Smillert                 copy = state->wsize - state->offset;
627a79de952Smillert                 if (copy < left) {
628a79de952Smillert                     from = put + copy;
629a79de952Smillert                     copy = left - copy;
630a79de952Smillert                 }
631a79de952Smillert                 else {
632a79de952Smillert                     from = put - state->offset;
633a79de952Smillert                     copy = left;
634a79de952Smillert                 }
635a79de952Smillert                 if (copy > state->length) copy = state->length;
636a79de952Smillert                 state->length -= copy;
637a79de952Smillert                 left -= copy;
638a79de952Smillert                 do {
639a79de952Smillert                     *put++ = *from++;
640a79de952Smillert                 } while (--copy);
641a79de952Smillert             } while (state->length != 0);
642a79de952Smillert             break;
643a79de952Smillert 
644a79de952Smillert         case DONE:
645ddf65acdStb             /* inflate stream terminated properly */
646a79de952Smillert             ret = Z_STREAM_END;
647a79de952Smillert             goto inf_leave;
648a79de952Smillert 
649a79de952Smillert         case BAD:
650a79de952Smillert             ret = Z_DATA_ERROR;
651a79de952Smillert             goto inf_leave;
652a79de952Smillert 
653ddf65acdStb         default:
654ddf65acdStb             /* can't happen, but makes compilers happy */
655a79de952Smillert             ret = Z_STREAM_ERROR;
656a79de952Smillert             goto inf_leave;
657a79de952Smillert         }
658a79de952Smillert 
659ddf65acdStb     /* Write leftover output and return unused input */
660a79de952Smillert   inf_leave:
661ddf65acdStb     if (left < state->wsize) {
662ddf65acdStb         if (out(out_desc, state->window, state->wsize - left) &&
663ddf65acdStb             ret == Z_STREAM_END)
664ddf65acdStb             ret = Z_BUF_ERROR;
665ddf65acdStb     }
666a79de952Smillert     strm->next_in = next;
667a79de952Smillert     strm->avail_in = have;
668a79de952Smillert     return ret;
669a79de952Smillert }
670a79de952Smillert 
inflateBackEnd(z_streamp strm)671cfac609cStb int ZEXPORT inflateBackEnd(z_streamp strm) {
672a79de952Smillert     if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
673a79de952Smillert         return Z_STREAM_ERROR;
6740258c1b1Stb     ZFREE(strm, strm->state, sizeof(struct inflate_state));
675a79de952Smillert     strm->state = Z_NULL;
676a79de952Smillert     Tracev((stderr, "inflate: end\n"));
677a79de952Smillert     return Z_OK;
678a79de952Smillert }
679