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