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