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