xref: /rk3399_ARM-atf/lib/zlib/inflate.c (revision a194255d75ed9e2ef56bd6e14349a3e7d86af934)
1221b1638SMasahiro Yamada /* inflate.c -- zlib decompression
2*a194255dSDaniel Boulby  * Copyright (C) 1995-2022 Mark Adler
3221b1638SMasahiro Yamada  * For conditions of distribution and use, see copyright notice in zlib.h
4221b1638SMasahiro Yamada  */
5221b1638SMasahiro Yamada 
6221b1638SMasahiro Yamada /*
7221b1638SMasahiro Yamada  * Change history:
8221b1638SMasahiro Yamada  *
9221b1638SMasahiro Yamada  * 1.2.beta0    24 Nov 2002
10221b1638SMasahiro Yamada  * - First version -- complete rewrite of inflate to simplify code, avoid
11221b1638SMasahiro Yamada  *   creation of window when not needed, minimize use of window when it is
12221b1638SMasahiro Yamada  *   needed, make inffast.c even faster, implement gzip decoding, and to
13221b1638SMasahiro Yamada  *   improve code readability and style over the previous zlib inflate code
14221b1638SMasahiro Yamada  *
15221b1638SMasahiro Yamada  * 1.2.beta1    25 Nov 2002
16221b1638SMasahiro Yamada  * - Use pointers for available input and output checking in inffast.c
17221b1638SMasahiro Yamada  * - Remove input and output counters in inffast.c
18221b1638SMasahiro Yamada  * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
19221b1638SMasahiro Yamada  * - Remove unnecessary second byte pull from length extra in inffast.c
20221b1638SMasahiro Yamada  * - Unroll direct copy to three copies per loop in inffast.c
21221b1638SMasahiro Yamada  *
22221b1638SMasahiro Yamada  * 1.2.beta2    4 Dec 2002
23221b1638SMasahiro Yamada  * - Change external routine names to reduce potential conflicts
24221b1638SMasahiro Yamada  * - Correct filename to inffixed.h for fixed tables in inflate.c
25221b1638SMasahiro Yamada  * - Make hbuf[] unsigned char to match parameter type in inflate.c
26221b1638SMasahiro Yamada  * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
27221b1638SMasahiro Yamada  *   to avoid negation problem on Alphas (64 bit) in inflate.c
28221b1638SMasahiro Yamada  *
29221b1638SMasahiro Yamada  * 1.2.beta3    22 Dec 2002
30221b1638SMasahiro Yamada  * - Add comments on state->bits assertion in inffast.c
31221b1638SMasahiro Yamada  * - Add comments on op field in inftrees.h
32221b1638SMasahiro Yamada  * - Fix bug in reuse of allocated window after inflateReset()
33221b1638SMasahiro Yamada  * - Remove bit fields--back to byte structure for speed
34221b1638SMasahiro Yamada  * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
35221b1638SMasahiro Yamada  * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
36221b1638SMasahiro Yamada  * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
37221b1638SMasahiro Yamada  * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
38221b1638SMasahiro Yamada  * - Use local copies of stream next and avail values, as well as local bit
39221b1638SMasahiro Yamada  *   buffer and bit count in inflate()--for speed when inflate_fast() not used
40221b1638SMasahiro Yamada  *
41221b1638SMasahiro Yamada  * 1.2.beta4    1 Jan 2003
42221b1638SMasahiro Yamada  * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
43221b1638SMasahiro Yamada  * - Move a comment on output buffer sizes from inffast.c to inflate.c
44221b1638SMasahiro Yamada  * - Add comments in inffast.c to introduce the inflate_fast() routine
45221b1638SMasahiro Yamada  * - Rearrange window copies in inflate_fast() for speed and simplification
46221b1638SMasahiro Yamada  * - Unroll last copy for window match in inflate_fast()
47221b1638SMasahiro Yamada  * - Use local copies of window variables in inflate_fast() for speed
48221b1638SMasahiro Yamada  * - Pull out common wnext == 0 case for speed in inflate_fast()
49221b1638SMasahiro Yamada  * - Make op and len in inflate_fast() unsigned for consistency
50221b1638SMasahiro Yamada  * - Add FAR to lcode and dcode declarations in inflate_fast()
51221b1638SMasahiro Yamada  * - Simplified bad distance check in inflate_fast()
52221b1638SMasahiro Yamada  * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
53221b1638SMasahiro Yamada  *   source file infback.c to provide a call-back interface to inflate for
54221b1638SMasahiro Yamada  *   programs like gzip and unzip -- uses window as output buffer to avoid
55221b1638SMasahiro Yamada  *   window copying
56221b1638SMasahiro Yamada  *
57221b1638SMasahiro Yamada  * 1.2.beta5    1 Jan 2003
58221b1638SMasahiro Yamada  * - Improved inflateBack() interface to allow the caller to provide initial
59221b1638SMasahiro Yamada  *   input in strm.
60221b1638SMasahiro Yamada  * - Fixed stored blocks bug in inflateBack()
61221b1638SMasahiro Yamada  *
62221b1638SMasahiro Yamada  * 1.2.beta6    4 Jan 2003
63221b1638SMasahiro Yamada  * - Added comments in inffast.c on effectiveness of POSTINC
64221b1638SMasahiro Yamada  * - Typecasting all around to reduce compiler warnings
65221b1638SMasahiro Yamada  * - Changed loops from while (1) or do {} while (1) to for (;;), again to
66221b1638SMasahiro Yamada  *   make compilers happy
67221b1638SMasahiro Yamada  * - Changed type of window in inflateBackInit() to unsigned char *
68221b1638SMasahiro Yamada  *
69221b1638SMasahiro Yamada  * 1.2.beta7    27 Jan 2003
70221b1638SMasahiro Yamada  * - Changed many types to unsigned or unsigned short to avoid warnings
71221b1638SMasahiro Yamada  * - Added inflateCopy() function
72221b1638SMasahiro Yamada  *
73221b1638SMasahiro Yamada  * 1.2.0        9 Mar 2003
74221b1638SMasahiro Yamada  * - Changed inflateBack() interface to provide separate opaque descriptors
75221b1638SMasahiro Yamada  *   for the in() and out() functions
76221b1638SMasahiro Yamada  * - Changed inflateBack() argument and in_func typedef to swap the length
77221b1638SMasahiro Yamada  *   and buffer address return values for the input function
78221b1638SMasahiro Yamada  * - Check next_in and next_out for Z_NULL on entry to inflate()
79221b1638SMasahiro Yamada  *
80221b1638SMasahiro Yamada  * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
81221b1638SMasahiro Yamada  */
82221b1638SMasahiro Yamada 
83221b1638SMasahiro Yamada #include "zutil.h"
84221b1638SMasahiro Yamada #include "inftrees.h"
85221b1638SMasahiro Yamada #include "inflate.h"
86221b1638SMasahiro Yamada #include "inffast.h"
87221b1638SMasahiro Yamada 
88221b1638SMasahiro Yamada #ifdef MAKEFIXED
89221b1638SMasahiro Yamada #  ifndef BUILDFIXED
90221b1638SMasahiro Yamada #    define BUILDFIXED
91221b1638SMasahiro Yamada #  endif
92221b1638SMasahiro Yamada #endif
93221b1638SMasahiro Yamada 
94221b1638SMasahiro Yamada /* function prototypes */
95221b1638SMasahiro Yamada local int inflateStateCheck OF((z_streamp strm));
96221b1638SMasahiro Yamada local void fixedtables OF((struct inflate_state FAR *state));
97221b1638SMasahiro Yamada local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
98221b1638SMasahiro Yamada                            unsigned copy));
99221b1638SMasahiro Yamada #ifdef BUILDFIXED
100221b1638SMasahiro Yamada    void makefixed OF((void));
101221b1638SMasahiro Yamada #endif
102221b1638SMasahiro Yamada local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
103221b1638SMasahiro Yamada                               unsigned len));
104221b1638SMasahiro Yamada 
105221b1638SMasahiro Yamada local int inflateStateCheck(strm)
106221b1638SMasahiro Yamada z_streamp strm;
107221b1638SMasahiro Yamada {
108221b1638SMasahiro Yamada     struct inflate_state FAR *state;
109221b1638SMasahiro Yamada     if (strm == Z_NULL ||
110221b1638SMasahiro Yamada         strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
111221b1638SMasahiro Yamada         return 1;
112221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
113221b1638SMasahiro Yamada     if (state == Z_NULL || state->strm != strm ||
114221b1638SMasahiro Yamada         state->mode < HEAD || state->mode > SYNC)
115221b1638SMasahiro Yamada         return 1;
116221b1638SMasahiro Yamada     return 0;
117221b1638SMasahiro Yamada }
118221b1638SMasahiro Yamada 
119221b1638SMasahiro Yamada int ZEXPORT inflateResetKeep(strm)
120221b1638SMasahiro Yamada z_streamp strm;
121221b1638SMasahiro Yamada {
122221b1638SMasahiro Yamada     struct inflate_state FAR *state;
123221b1638SMasahiro Yamada 
124221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
125221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
126221b1638SMasahiro Yamada     strm->total_in = strm->total_out = state->total = 0;
127221b1638SMasahiro Yamada     strm->msg = Z_NULL;
128221b1638SMasahiro Yamada     if (state->wrap)        /* to support ill-conceived Java test suite */
129221b1638SMasahiro Yamada         strm->adler = state->wrap & 1;
130221b1638SMasahiro Yamada     state->mode = HEAD;
131221b1638SMasahiro Yamada     state->last = 0;
132221b1638SMasahiro Yamada     state->havedict = 0;
133*a194255dSDaniel Boulby     state->flags = -1;
134221b1638SMasahiro Yamada     state->dmax = 32768U;
135221b1638SMasahiro Yamada     state->head = Z_NULL;
136221b1638SMasahiro Yamada     state->hold = 0;
137221b1638SMasahiro Yamada     state->bits = 0;
138221b1638SMasahiro Yamada     state->lencode = state->distcode = state->next = state->codes;
139221b1638SMasahiro Yamada     state->sane = 1;
140221b1638SMasahiro Yamada     state->back = -1;
141221b1638SMasahiro Yamada     Tracev((stderr, "inflate: reset\n"));
142221b1638SMasahiro Yamada     return Z_OK;
143221b1638SMasahiro Yamada }
144221b1638SMasahiro Yamada 
145221b1638SMasahiro Yamada int ZEXPORT inflateReset(strm)
146221b1638SMasahiro Yamada z_streamp strm;
147221b1638SMasahiro Yamada {
148221b1638SMasahiro Yamada     struct inflate_state FAR *state;
149221b1638SMasahiro Yamada 
150221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
151221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
152221b1638SMasahiro Yamada     state->wsize = 0;
153221b1638SMasahiro Yamada     state->whave = 0;
154221b1638SMasahiro Yamada     state->wnext = 0;
155221b1638SMasahiro Yamada     return inflateResetKeep(strm);
156221b1638SMasahiro Yamada }
157221b1638SMasahiro Yamada 
158221b1638SMasahiro Yamada int ZEXPORT inflateReset2(strm, windowBits)
159221b1638SMasahiro Yamada z_streamp strm;
160221b1638SMasahiro Yamada int windowBits;
161221b1638SMasahiro Yamada {
162221b1638SMasahiro Yamada     int wrap;
163221b1638SMasahiro Yamada     struct inflate_state FAR *state;
164221b1638SMasahiro Yamada 
165221b1638SMasahiro Yamada     /* get the state */
166221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
167221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
168221b1638SMasahiro Yamada 
169221b1638SMasahiro Yamada     /* extract wrap request from windowBits parameter */
170221b1638SMasahiro Yamada     if (windowBits < 0) {
171*a194255dSDaniel Boulby         if (windowBits < -15)
172*a194255dSDaniel Boulby             return Z_STREAM_ERROR;
173221b1638SMasahiro Yamada         wrap = 0;
174221b1638SMasahiro Yamada         windowBits = -windowBits;
175221b1638SMasahiro Yamada     }
176221b1638SMasahiro Yamada     else {
177221b1638SMasahiro Yamada         wrap = (windowBits >> 4) + 5;
178221b1638SMasahiro Yamada #ifdef GUNZIP
179221b1638SMasahiro Yamada         if (windowBits < 48)
180221b1638SMasahiro Yamada             windowBits &= 15;
181221b1638SMasahiro Yamada #endif
182221b1638SMasahiro Yamada     }
183221b1638SMasahiro Yamada 
184221b1638SMasahiro Yamada     /* set number of window bits, free window if different */
185221b1638SMasahiro Yamada     if (windowBits && (windowBits < 8 || windowBits > 15))
186221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
187221b1638SMasahiro Yamada     if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
188221b1638SMasahiro Yamada         ZFREE(strm, state->window);
189221b1638SMasahiro Yamada         state->window = Z_NULL;
190221b1638SMasahiro Yamada     }
191221b1638SMasahiro Yamada 
192221b1638SMasahiro Yamada     /* update state and reset the rest of it */
193221b1638SMasahiro Yamada     state->wrap = wrap;
194221b1638SMasahiro Yamada     state->wbits = (unsigned)windowBits;
195221b1638SMasahiro Yamada     return inflateReset(strm);
196221b1638SMasahiro Yamada }
197221b1638SMasahiro Yamada 
198221b1638SMasahiro Yamada int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
199221b1638SMasahiro Yamada z_streamp strm;
200221b1638SMasahiro Yamada int windowBits;
201221b1638SMasahiro Yamada const char *version;
202221b1638SMasahiro Yamada int stream_size;
203221b1638SMasahiro Yamada {
204221b1638SMasahiro Yamada     int ret;
205221b1638SMasahiro Yamada     struct inflate_state FAR *state;
206221b1638SMasahiro Yamada 
207221b1638SMasahiro Yamada     if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
208221b1638SMasahiro Yamada         stream_size != (int)(sizeof(z_stream)))
209221b1638SMasahiro Yamada         return Z_VERSION_ERROR;
210221b1638SMasahiro Yamada     if (strm == Z_NULL) return Z_STREAM_ERROR;
211221b1638SMasahiro Yamada     strm->msg = Z_NULL;                 /* in case we return an error */
212221b1638SMasahiro Yamada     if (strm->zalloc == (alloc_func)0) {
213221b1638SMasahiro Yamada #ifdef Z_SOLO
214221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
215221b1638SMasahiro Yamada #else
216221b1638SMasahiro Yamada         strm->zalloc = zcalloc;
217221b1638SMasahiro Yamada         strm->opaque = (voidpf)0;
218221b1638SMasahiro Yamada #endif
219221b1638SMasahiro Yamada     }
220221b1638SMasahiro Yamada     if (strm->zfree == (free_func)0)
221221b1638SMasahiro Yamada #ifdef Z_SOLO
222221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
223221b1638SMasahiro Yamada #else
224221b1638SMasahiro Yamada         strm->zfree = zcfree;
225221b1638SMasahiro Yamada #endif
226221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)
227221b1638SMasahiro Yamada             ZALLOC(strm, 1, sizeof(struct inflate_state));
228221b1638SMasahiro Yamada     if (state == Z_NULL) return Z_MEM_ERROR;
229221b1638SMasahiro Yamada     Tracev((stderr, "inflate: allocated\n"));
230221b1638SMasahiro Yamada     strm->state = (struct internal_state FAR *)state;
231221b1638SMasahiro Yamada     state->strm = strm;
232221b1638SMasahiro Yamada     state->window = Z_NULL;
233221b1638SMasahiro Yamada     state->mode = HEAD;     /* to pass state test in inflateReset2() */
234221b1638SMasahiro Yamada     ret = inflateReset2(strm, windowBits);
235221b1638SMasahiro Yamada     if (ret != Z_OK) {
236221b1638SMasahiro Yamada         ZFREE(strm, state);
237221b1638SMasahiro Yamada         strm->state = Z_NULL;
238221b1638SMasahiro Yamada     }
239221b1638SMasahiro Yamada     return ret;
240221b1638SMasahiro Yamada }
241221b1638SMasahiro Yamada 
242221b1638SMasahiro Yamada int ZEXPORT inflateInit_(strm, version, stream_size)
243221b1638SMasahiro Yamada z_streamp strm;
244221b1638SMasahiro Yamada const char *version;
245221b1638SMasahiro Yamada int stream_size;
246221b1638SMasahiro Yamada {
247221b1638SMasahiro Yamada     return inflateInit2_(strm, DEF_WBITS, version, stream_size);
248221b1638SMasahiro Yamada }
249221b1638SMasahiro Yamada 
250221b1638SMasahiro Yamada int ZEXPORT inflatePrime(strm, bits, value)
251221b1638SMasahiro Yamada z_streamp strm;
252221b1638SMasahiro Yamada int bits;
253221b1638SMasahiro Yamada int value;
254221b1638SMasahiro Yamada {
255221b1638SMasahiro Yamada     struct inflate_state FAR *state;
256221b1638SMasahiro Yamada 
257221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
258221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
259221b1638SMasahiro Yamada     if (bits < 0) {
260221b1638SMasahiro Yamada         state->hold = 0;
261221b1638SMasahiro Yamada         state->bits = 0;
262221b1638SMasahiro Yamada         return Z_OK;
263221b1638SMasahiro Yamada     }
264221b1638SMasahiro Yamada     if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;
265221b1638SMasahiro Yamada     value &= (1L << bits) - 1;
266221b1638SMasahiro Yamada     state->hold += (unsigned)value << state->bits;
267221b1638SMasahiro Yamada     state->bits += (uInt)bits;
268221b1638SMasahiro Yamada     return Z_OK;
269221b1638SMasahiro Yamada }
270221b1638SMasahiro Yamada 
271221b1638SMasahiro Yamada /*
272221b1638SMasahiro Yamada    Return state with length and distance decoding tables and index sizes set to
273221b1638SMasahiro Yamada    fixed code decoding.  Normally this returns fixed tables from inffixed.h.
274221b1638SMasahiro Yamada    If BUILDFIXED is defined, then instead this routine builds the tables the
275221b1638SMasahiro Yamada    first time it's called, and returns those tables the first time and
276221b1638SMasahiro Yamada    thereafter.  This reduces the size of the code by about 2K bytes, in
277221b1638SMasahiro Yamada    exchange for a little execution time.  However, BUILDFIXED should not be
278221b1638SMasahiro Yamada    used for threaded applications, since the rewriting of the tables and virgin
279221b1638SMasahiro Yamada    may not be thread-safe.
280221b1638SMasahiro Yamada  */
281221b1638SMasahiro Yamada local void fixedtables(state)
282221b1638SMasahiro Yamada struct inflate_state FAR *state;
283221b1638SMasahiro Yamada {
284221b1638SMasahiro Yamada #ifdef BUILDFIXED
285221b1638SMasahiro Yamada     static int virgin = 1;
286221b1638SMasahiro Yamada     static code *lenfix, *distfix;
287221b1638SMasahiro Yamada     static code fixed[544];
288221b1638SMasahiro Yamada 
289221b1638SMasahiro Yamada     /* build fixed huffman tables if first call (may not be thread safe) */
290221b1638SMasahiro Yamada     if (virgin) {
291221b1638SMasahiro Yamada         unsigned sym, bits;
292221b1638SMasahiro Yamada         static code *next;
293221b1638SMasahiro Yamada 
294221b1638SMasahiro Yamada         /* literal/length table */
295221b1638SMasahiro Yamada         sym = 0;
296221b1638SMasahiro Yamada         while (sym < 144) state->lens[sym++] = 8;
297221b1638SMasahiro Yamada         while (sym < 256) state->lens[sym++] = 9;
298221b1638SMasahiro Yamada         while (sym < 280) state->lens[sym++] = 7;
299221b1638SMasahiro Yamada         while (sym < 288) state->lens[sym++] = 8;
300221b1638SMasahiro Yamada         next = fixed;
301221b1638SMasahiro Yamada         lenfix = next;
302221b1638SMasahiro Yamada         bits = 9;
303221b1638SMasahiro Yamada         inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
304221b1638SMasahiro Yamada 
305221b1638SMasahiro Yamada         /* distance table */
306221b1638SMasahiro Yamada         sym = 0;
307221b1638SMasahiro Yamada         while (sym < 32) state->lens[sym++] = 5;
308221b1638SMasahiro Yamada         distfix = next;
309221b1638SMasahiro Yamada         bits = 5;
310221b1638SMasahiro Yamada         inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
311221b1638SMasahiro Yamada 
312221b1638SMasahiro Yamada         /* do this just once */
313221b1638SMasahiro Yamada         virgin = 0;
314221b1638SMasahiro Yamada     }
315221b1638SMasahiro Yamada #else /* !BUILDFIXED */
316221b1638SMasahiro Yamada #   include "inffixed.h"
317221b1638SMasahiro Yamada #endif /* BUILDFIXED */
318221b1638SMasahiro Yamada     state->lencode = lenfix;
319221b1638SMasahiro Yamada     state->lenbits = 9;
320221b1638SMasahiro Yamada     state->distcode = distfix;
321221b1638SMasahiro Yamada     state->distbits = 5;
322221b1638SMasahiro Yamada }
323221b1638SMasahiro Yamada 
324221b1638SMasahiro Yamada #ifdef MAKEFIXED
325221b1638SMasahiro Yamada #include <stdio.h>
326221b1638SMasahiro Yamada 
327221b1638SMasahiro Yamada /*
328221b1638SMasahiro Yamada    Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
329221b1638SMasahiro Yamada    defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
330221b1638SMasahiro Yamada    those tables to stdout, which would be piped to inffixed.h.  A small program
331221b1638SMasahiro Yamada    can simply call makefixed to do this:
332221b1638SMasahiro Yamada 
333221b1638SMasahiro Yamada     void makefixed(void);
334221b1638SMasahiro Yamada 
335221b1638SMasahiro Yamada     int main(void)
336221b1638SMasahiro Yamada     {
337221b1638SMasahiro Yamada         makefixed();
338221b1638SMasahiro Yamada         return 0;
339221b1638SMasahiro Yamada     }
340221b1638SMasahiro Yamada 
341221b1638SMasahiro Yamada    Then that can be linked with zlib built with MAKEFIXED defined and run:
342221b1638SMasahiro Yamada 
343221b1638SMasahiro Yamada     a.out > inffixed.h
344221b1638SMasahiro Yamada  */
345221b1638SMasahiro Yamada void makefixed()
346221b1638SMasahiro Yamada {
347221b1638SMasahiro Yamada     unsigned low, size;
348221b1638SMasahiro Yamada     struct inflate_state state;
349221b1638SMasahiro Yamada 
350221b1638SMasahiro Yamada     fixedtables(&state);
351221b1638SMasahiro Yamada     puts("    /* inffixed.h -- table for decoding fixed codes");
352221b1638SMasahiro Yamada     puts("     * Generated automatically by makefixed().");
353221b1638SMasahiro Yamada     puts("     */");
354221b1638SMasahiro Yamada     puts("");
355221b1638SMasahiro Yamada     puts("    /* WARNING: this file should *not* be used by applications.");
356221b1638SMasahiro Yamada     puts("       It is part of the implementation of this library and is");
357221b1638SMasahiro Yamada     puts("       subject to change. Applications should only use zlib.h.");
358221b1638SMasahiro Yamada     puts("     */");
359221b1638SMasahiro Yamada     puts("");
360221b1638SMasahiro Yamada     size = 1U << 9;
361221b1638SMasahiro Yamada     printf("    static const code lenfix[%u] = {", size);
362221b1638SMasahiro Yamada     low = 0;
363221b1638SMasahiro Yamada     for (;;) {
364221b1638SMasahiro Yamada         if ((low % 7) == 0) printf("\n        ");
365221b1638SMasahiro Yamada         printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
366221b1638SMasahiro Yamada                state.lencode[low].bits, state.lencode[low].val);
367221b1638SMasahiro Yamada         if (++low == size) break;
368221b1638SMasahiro Yamada         putchar(',');
369221b1638SMasahiro Yamada     }
370221b1638SMasahiro Yamada     puts("\n    };");
371221b1638SMasahiro Yamada     size = 1U << 5;
372221b1638SMasahiro Yamada     printf("\n    static const code distfix[%u] = {", size);
373221b1638SMasahiro Yamada     low = 0;
374221b1638SMasahiro Yamada     for (;;) {
375221b1638SMasahiro Yamada         if ((low % 6) == 0) printf("\n        ");
376221b1638SMasahiro Yamada         printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
377221b1638SMasahiro Yamada                state.distcode[low].val);
378221b1638SMasahiro Yamada         if (++low == size) break;
379221b1638SMasahiro Yamada         putchar(',');
380221b1638SMasahiro Yamada     }
381221b1638SMasahiro Yamada     puts("\n    };");
382221b1638SMasahiro Yamada }
383221b1638SMasahiro Yamada #endif /* MAKEFIXED */
384221b1638SMasahiro Yamada 
385221b1638SMasahiro Yamada /*
386221b1638SMasahiro Yamada    Update the window with the last wsize (normally 32K) bytes written before
387221b1638SMasahiro Yamada    returning.  If window does not exist yet, create it.  This is only called
388221b1638SMasahiro Yamada    when a window is already in use, or when output has been written during this
389221b1638SMasahiro Yamada    inflate call, but the end of the deflate stream has not been reached yet.
390221b1638SMasahiro Yamada    It is also called to create a window for dictionary data when a dictionary
391221b1638SMasahiro Yamada    is loaded.
392221b1638SMasahiro Yamada 
393221b1638SMasahiro Yamada    Providing output buffers larger than 32K to inflate() should provide a speed
394221b1638SMasahiro Yamada    advantage, since only the last 32K of output is copied to the sliding window
395221b1638SMasahiro Yamada    upon return from inflate(), and since all distances after the first 32K of
396221b1638SMasahiro Yamada    output will fall in the output data, making match copies simpler and faster.
397221b1638SMasahiro Yamada    The advantage may be dependent on the size of the processor's data caches.
398221b1638SMasahiro Yamada  */
399221b1638SMasahiro Yamada local int updatewindow(strm, end, copy)
400221b1638SMasahiro Yamada z_streamp strm;
401221b1638SMasahiro Yamada const Bytef *end;
402221b1638SMasahiro Yamada unsigned copy;
403221b1638SMasahiro Yamada {
404221b1638SMasahiro Yamada     struct inflate_state FAR *state;
405221b1638SMasahiro Yamada     unsigned dist;
406221b1638SMasahiro Yamada 
407221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
408221b1638SMasahiro Yamada 
409221b1638SMasahiro Yamada     /* if it hasn't been done already, allocate space for the window */
410221b1638SMasahiro Yamada     if (state->window == Z_NULL) {
411221b1638SMasahiro Yamada         state->window = (unsigned char FAR *)
412221b1638SMasahiro Yamada                         ZALLOC(strm, 1U << state->wbits,
413221b1638SMasahiro Yamada                                sizeof(unsigned char));
414221b1638SMasahiro Yamada         if (state->window == Z_NULL) return 1;
415221b1638SMasahiro Yamada     }
416221b1638SMasahiro Yamada 
417221b1638SMasahiro Yamada     /* if window not in use yet, initialize */
418221b1638SMasahiro Yamada     if (state->wsize == 0) {
419221b1638SMasahiro Yamada         state->wsize = 1U << state->wbits;
420221b1638SMasahiro Yamada         state->wnext = 0;
421221b1638SMasahiro Yamada         state->whave = 0;
422221b1638SMasahiro Yamada     }
423221b1638SMasahiro Yamada 
424221b1638SMasahiro Yamada     /* copy state->wsize or less output bytes into the circular window */
425221b1638SMasahiro Yamada     if (copy >= state->wsize) {
426221b1638SMasahiro Yamada         zmemcpy(state->window, end - state->wsize, state->wsize);
427221b1638SMasahiro Yamada         state->wnext = 0;
428221b1638SMasahiro Yamada         state->whave = state->wsize;
429221b1638SMasahiro Yamada     }
430221b1638SMasahiro Yamada     else {
431221b1638SMasahiro Yamada         dist = state->wsize - state->wnext;
432221b1638SMasahiro Yamada         if (dist > copy) dist = copy;
433221b1638SMasahiro Yamada         zmemcpy(state->window + state->wnext, end - copy, dist);
434221b1638SMasahiro Yamada         copy -= dist;
435221b1638SMasahiro Yamada         if (copy) {
436221b1638SMasahiro Yamada             zmemcpy(state->window, end - copy, copy);
437221b1638SMasahiro Yamada             state->wnext = copy;
438221b1638SMasahiro Yamada             state->whave = state->wsize;
439221b1638SMasahiro Yamada         }
440221b1638SMasahiro Yamada         else {
441221b1638SMasahiro Yamada             state->wnext += dist;
442221b1638SMasahiro Yamada             if (state->wnext == state->wsize) state->wnext = 0;
443221b1638SMasahiro Yamada             if (state->whave < state->wsize) state->whave += dist;
444221b1638SMasahiro Yamada         }
445221b1638SMasahiro Yamada     }
446221b1638SMasahiro Yamada     return 0;
447221b1638SMasahiro Yamada }
448221b1638SMasahiro Yamada 
449221b1638SMasahiro Yamada /* Macros for inflate(): */
450221b1638SMasahiro Yamada 
451221b1638SMasahiro Yamada /* check function to use adler32() for zlib or crc32() for gzip */
452221b1638SMasahiro Yamada #ifdef GUNZIP
453*a194255dSDaniel Boulby #  define UPDATE_CHECK(check, buf, len) \
454221b1638SMasahiro Yamada     (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
455221b1638SMasahiro Yamada #else
456*a194255dSDaniel Boulby #  define UPDATE_CHECK(check, buf, len) adler32(check, buf, len)
457221b1638SMasahiro Yamada #endif
458221b1638SMasahiro Yamada 
459221b1638SMasahiro Yamada /* check macros for header crc */
460221b1638SMasahiro Yamada #ifdef GUNZIP
461221b1638SMasahiro Yamada #  define CRC2(check, word) \
462221b1638SMasahiro Yamada     do { \
463221b1638SMasahiro Yamada         hbuf[0] = (unsigned char)(word); \
464221b1638SMasahiro Yamada         hbuf[1] = (unsigned char)((word) >> 8); \
465221b1638SMasahiro Yamada         check = crc32(check, hbuf, 2); \
466221b1638SMasahiro Yamada     } while (0)
467221b1638SMasahiro Yamada 
468221b1638SMasahiro Yamada #  define CRC4(check, word) \
469221b1638SMasahiro Yamada     do { \
470221b1638SMasahiro Yamada         hbuf[0] = (unsigned char)(word); \
471221b1638SMasahiro Yamada         hbuf[1] = (unsigned char)((word) >> 8); \
472221b1638SMasahiro Yamada         hbuf[2] = (unsigned char)((word) >> 16); \
473221b1638SMasahiro Yamada         hbuf[3] = (unsigned char)((word) >> 24); \
474221b1638SMasahiro Yamada         check = crc32(check, hbuf, 4); \
475221b1638SMasahiro Yamada     } while (0)
476221b1638SMasahiro Yamada #endif
477221b1638SMasahiro Yamada 
478221b1638SMasahiro Yamada /* Load registers with state in inflate() for speed */
479221b1638SMasahiro Yamada #define LOAD() \
480221b1638SMasahiro Yamada     do { \
481221b1638SMasahiro Yamada         put = strm->next_out; \
482221b1638SMasahiro Yamada         left = strm->avail_out; \
483221b1638SMasahiro Yamada         next = strm->next_in; \
484221b1638SMasahiro Yamada         have = strm->avail_in; \
485221b1638SMasahiro Yamada         hold = state->hold; \
486221b1638SMasahiro Yamada         bits = state->bits; \
487221b1638SMasahiro Yamada     } while (0)
488221b1638SMasahiro Yamada 
489221b1638SMasahiro Yamada /* Restore state from registers in inflate() */
490221b1638SMasahiro Yamada #define RESTORE() \
491221b1638SMasahiro Yamada     do { \
492221b1638SMasahiro Yamada         strm->next_out = put; \
493221b1638SMasahiro Yamada         strm->avail_out = left; \
494221b1638SMasahiro Yamada         strm->next_in = next; \
495221b1638SMasahiro Yamada         strm->avail_in = have; \
496221b1638SMasahiro Yamada         state->hold = hold; \
497221b1638SMasahiro Yamada         state->bits = bits; \
498221b1638SMasahiro Yamada     } while (0)
499221b1638SMasahiro Yamada 
500221b1638SMasahiro Yamada /* Clear the input bit accumulator */
501221b1638SMasahiro Yamada #define INITBITS() \
502221b1638SMasahiro Yamada     do { \
503221b1638SMasahiro Yamada         hold = 0; \
504221b1638SMasahiro Yamada         bits = 0; \
505221b1638SMasahiro Yamada     } while (0)
506221b1638SMasahiro Yamada 
507221b1638SMasahiro Yamada /* Get a byte of input into the bit accumulator, or return from inflate()
508221b1638SMasahiro Yamada    if there is no input available. */
509221b1638SMasahiro Yamada #define PULLBYTE() \
510221b1638SMasahiro Yamada     do { \
511221b1638SMasahiro Yamada         if (have == 0) goto inf_leave; \
512221b1638SMasahiro Yamada         have--; \
513221b1638SMasahiro Yamada         hold += (unsigned long)(*next++) << bits; \
514221b1638SMasahiro Yamada         bits += 8; \
515221b1638SMasahiro Yamada     } while (0)
516221b1638SMasahiro Yamada 
517221b1638SMasahiro Yamada /* Assure that there are at least n bits in the bit accumulator.  If there is
518221b1638SMasahiro Yamada    not enough available input to do that, then return from inflate(). */
519221b1638SMasahiro Yamada #define NEEDBITS(n) \
520221b1638SMasahiro Yamada     do { \
521221b1638SMasahiro Yamada         while (bits < (unsigned)(n)) \
522221b1638SMasahiro Yamada             PULLBYTE(); \
523221b1638SMasahiro Yamada     } while (0)
524221b1638SMasahiro Yamada 
525221b1638SMasahiro Yamada /* Return the low n bits of the bit accumulator (n < 16) */
526221b1638SMasahiro Yamada #define BITS(n) \
527221b1638SMasahiro Yamada     ((unsigned)hold & ((1U << (n)) - 1))
528221b1638SMasahiro Yamada 
529221b1638SMasahiro Yamada /* Remove n bits from the bit accumulator */
530221b1638SMasahiro Yamada #define DROPBITS(n) \
531221b1638SMasahiro Yamada     do { \
532221b1638SMasahiro Yamada         hold >>= (n); \
533221b1638SMasahiro Yamada         bits -= (unsigned)(n); \
534221b1638SMasahiro Yamada     } while (0)
535221b1638SMasahiro Yamada 
536221b1638SMasahiro Yamada /* Remove zero to seven bits as needed to go to a byte boundary */
537221b1638SMasahiro Yamada #define BYTEBITS() \
538221b1638SMasahiro Yamada     do { \
539221b1638SMasahiro Yamada         hold >>= bits & 7; \
540221b1638SMasahiro Yamada         bits -= bits & 7; \
541221b1638SMasahiro Yamada     } while (0)
542221b1638SMasahiro Yamada 
543221b1638SMasahiro Yamada /*
544221b1638SMasahiro Yamada    inflate() uses a state machine to process as much input data and generate as
545221b1638SMasahiro Yamada    much output data as possible before returning.  The state machine is
546221b1638SMasahiro Yamada    structured roughly as follows:
547221b1638SMasahiro Yamada 
548221b1638SMasahiro Yamada     for (;;) switch (state) {
549221b1638SMasahiro Yamada     ...
550221b1638SMasahiro Yamada     case STATEn:
551221b1638SMasahiro Yamada         if (not enough input data or output space to make progress)
552221b1638SMasahiro Yamada             return;
553221b1638SMasahiro Yamada         ... make progress ...
554221b1638SMasahiro Yamada         state = STATEm;
555221b1638SMasahiro Yamada         break;
556221b1638SMasahiro Yamada     ...
557221b1638SMasahiro Yamada     }
558221b1638SMasahiro Yamada 
559221b1638SMasahiro Yamada    so when inflate() is called again, the same case is attempted again, and
560221b1638SMasahiro Yamada    if the appropriate resources are provided, the machine proceeds to the
561221b1638SMasahiro Yamada    next state.  The NEEDBITS() macro is usually the way the state evaluates
562221b1638SMasahiro Yamada    whether it can proceed or should return.  NEEDBITS() does the return if
563221b1638SMasahiro Yamada    the requested bits are not available.  The typical use of the BITS macros
564221b1638SMasahiro Yamada    is:
565221b1638SMasahiro Yamada 
566221b1638SMasahiro Yamada         NEEDBITS(n);
567221b1638SMasahiro Yamada         ... do something with BITS(n) ...
568221b1638SMasahiro Yamada         DROPBITS(n);
569221b1638SMasahiro Yamada 
570221b1638SMasahiro Yamada    where NEEDBITS(n) either returns from inflate() if there isn't enough
571221b1638SMasahiro Yamada    input left to load n bits into the accumulator, or it continues.  BITS(n)
572221b1638SMasahiro Yamada    gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
573221b1638SMasahiro Yamada    the low n bits off the accumulator.  INITBITS() clears the accumulator
574221b1638SMasahiro Yamada    and sets the number of available bits to zero.  BYTEBITS() discards just
575221b1638SMasahiro Yamada    enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
576221b1638SMasahiro Yamada    and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
577221b1638SMasahiro Yamada 
578221b1638SMasahiro Yamada    NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
579221b1638SMasahiro Yamada    if there is no input available.  The decoding of variable length codes uses
580221b1638SMasahiro Yamada    PULLBYTE() directly in order to pull just enough bytes to decode the next
581221b1638SMasahiro Yamada    code, and no more.
582221b1638SMasahiro Yamada 
583221b1638SMasahiro Yamada    Some states loop until they get enough input, making sure that enough
584221b1638SMasahiro Yamada    state information is maintained to continue the loop where it left off
585221b1638SMasahiro Yamada    if NEEDBITS() returns in the loop.  For example, want, need, and keep
586221b1638SMasahiro Yamada    would all have to actually be part of the saved state in case NEEDBITS()
587221b1638SMasahiro Yamada    returns:
588221b1638SMasahiro Yamada 
589221b1638SMasahiro Yamada     case STATEw:
590221b1638SMasahiro Yamada         while (want < need) {
591221b1638SMasahiro Yamada             NEEDBITS(n);
592221b1638SMasahiro Yamada             keep[want++] = BITS(n);
593221b1638SMasahiro Yamada             DROPBITS(n);
594221b1638SMasahiro Yamada         }
595221b1638SMasahiro Yamada         state = STATEx;
596221b1638SMasahiro Yamada     case STATEx:
597221b1638SMasahiro Yamada 
598221b1638SMasahiro Yamada    As shown above, if the next state is also the next case, then the break
599221b1638SMasahiro Yamada    is omitted.
600221b1638SMasahiro Yamada 
601221b1638SMasahiro Yamada    A state may also return if there is not enough output space available to
602221b1638SMasahiro Yamada    complete that state.  Those states are copying stored data, writing a
603221b1638SMasahiro Yamada    literal byte, and copying a matching string.
604221b1638SMasahiro Yamada 
605221b1638SMasahiro Yamada    When returning, a "goto inf_leave" is used to update the total counters,
606221b1638SMasahiro Yamada    update the check value, and determine whether any progress has been made
607221b1638SMasahiro Yamada    during that inflate() call in order to return the proper return code.
608221b1638SMasahiro Yamada    Progress is defined as a change in either strm->avail_in or strm->avail_out.
609221b1638SMasahiro Yamada    When there is a window, goto inf_leave will update the window with the last
610221b1638SMasahiro Yamada    output written.  If a goto inf_leave occurs in the middle of decompression
611221b1638SMasahiro Yamada    and there is no window currently, goto inf_leave will create one and copy
612221b1638SMasahiro Yamada    output to the window for the next call of inflate().
613221b1638SMasahiro Yamada 
614221b1638SMasahiro Yamada    In this implementation, the flush parameter of inflate() only affects the
615221b1638SMasahiro Yamada    return code (per zlib.h).  inflate() always writes as much as possible to
616221b1638SMasahiro Yamada    strm->next_out, given the space available and the provided input--the effect
617221b1638SMasahiro Yamada    documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
618221b1638SMasahiro Yamada    the allocation of and copying into a sliding window until necessary, which
619221b1638SMasahiro Yamada    provides the effect documented in zlib.h for Z_FINISH when the entire input
620221b1638SMasahiro Yamada    stream available.  So the only thing the flush parameter actually does is:
621221b1638SMasahiro Yamada    when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
622221b1638SMasahiro Yamada    will return Z_BUF_ERROR if it has not reached the end of the stream.
623221b1638SMasahiro Yamada  */
624221b1638SMasahiro Yamada 
625221b1638SMasahiro Yamada int ZEXPORT inflate(strm, flush)
626221b1638SMasahiro Yamada z_streamp strm;
627221b1638SMasahiro Yamada int flush;
628221b1638SMasahiro Yamada {
629221b1638SMasahiro Yamada     struct inflate_state FAR *state;
630221b1638SMasahiro Yamada     z_const unsigned char FAR *next;    /* next input */
631221b1638SMasahiro Yamada     unsigned char FAR *put;     /* next output */
632221b1638SMasahiro Yamada     unsigned have, left;        /* available input and output */
633221b1638SMasahiro Yamada     unsigned long hold;         /* bit buffer */
634221b1638SMasahiro Yamada     unsigned bits;              /* bits in bit buffer */
635221b1638SMasahiro Yamada     unsigned in, out;           /* save starting available input and output */
636221b1638SMasahiro Yamada     unsigned copy;              /* number of stored or match bytes to copy */
637221b1638SMasahiro Yamada     unsigned char FAR *from;    /* where to copy match bytes from */
638221b1638SMasahiro Yamada     code here;                  /* current decoding table entry */
639221b1638SMasahiro Yamada     code last;                  /* parent table entry */
640221b1638SMasahiro Yamada     unsigned len;               /* length to copy for repeats, bits to drop */
641221b1638SMasahiro Yamada     int ret;                    /* return code */
642221b1638SMasahiro Yamada #ifdef GUNZIP
643221b1638SMasahiro Yamada     unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
644221b1638SMasahiro Yamada #endif
645221b1638SMasahiro Yamada     static const unsigned short order[19] = /* permutation of code lengths */
646221b1638SMasahiro Yamada         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
647221b1638SMasahiro Yamada 
648221b1638SMasahiro Yamada     if (inflateStateCheck(strm) || strm->next_out == Z_NULL ||
649221b1638SMasahiro Yamada         (strm->next_in == Z_NULL && strm->avail_in != 0))
650221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
651221b1638SMasahiro Yamada 
652221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
653221b1638SMasahiro Yamada     if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
654221b1638SMasahiro Yamada     LOAD();
655221b1638SMasahiro Yamada     in = have;
656221b1638SMasahiro Yamada     out = left;
657221b1638SMasahiro Yamada     ret = Z_OK;
658221b1638SMasahiro Yamada     for (;;)
659221b1638SMasahiro Yamada         switch (state->mode) {
660221b1638SMasahiro Yamada         case HEAD:
661221b1638SMasahiro Yamada             if (state->wrap == 0) {
662221b1638SMasahiro Yamada                 state->mode = TYPEDO;
663221b1638SMasahiro Yamada                 break;
664221b1638SMasahiro Yamada             }
665221b1638SMasahiro Yamada             NEEDBITS(16);
666221b1638SMasahiro Yamada #ifdef GUNZIP
667221b1638SMasahiro Yamada             if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
668221b1638SMasahiro Yamada                 if (state->wbits == 0)
669221b1638SMasahiro Yamada                     state->wbits = 15;
670221b1638SMasahiro Yamada                 state->check = crc32(0L, Z_NULL, 0);
671221b1638SMasahiro Yamada                 CRC2(state->check, hold);
672221b1638SMasahiro Yamada                 INITBITS();
673221b1638SMasahiro Yamada                 state->mode = FLAGS;
674221b1638SMasahiro Yamada                 break;
675221b1638SMasahiro Yamada             }
676221b1638SMasahiro Yamada             if (state->head != Z_NULL)
677221b1638SMasahiro Yamada                 state->head->done = -1;
678221b1638SMasahiro Yamada             if (!(state->wrap & 1) ||   /* check if zlib header allowed */
679221b1638SMasahiro Yamada #else
680221b1638SMasahiro Yamada             if (
681221b1638SMasahiro Yamada #endif
682221b1638SMasahiro Yamada                 ((BITS(8) << 8) + (hold >> 8)) % 31) {
683221b1638SMasahiro Yamada                 strm->msg = (char *)"incorrect header check";
684221b1638SMasahiro Yamada                 state->mode = BAD;
685221b1638SMasahiro Yamada                 break;
686221b1638SMasahiro Yamada             }
687221b1638SMasahiro Yamada             if (BITS(4) != Z_DEFLATED) {
688221b1638SMasahiro Yamada                 strm->msg = (char *)"unknown compression method";
689221b1638SMasahiro Yamada                 state->mode = BAD;
690221b1638SMasahiro Yamada                 break;
691221b1638SMasahiro Yamada             }
692221b1638SMasahiro Yamada             DROPBITS(4);
693221b1638SMasahiro Yamada             len = BITS(4) + 8;
694221b1638SMasahiro Yamada             if (state->wbits == 0)
695221b1638SMasahiro Yamada                 state->wbits = len;
696221b1638SMasahiro Yamada             if (len > 15 || len > state->wbits) {
697221b1638SMasahiro Yamada                 strm->msg = (char *)"invalid window size";
698221b1638SMasahiro Yamada                 state->mode = BAD;
699221b1638SMasahiro Yamada                 break;
700221b1638SMasahiro Yamada             }
701221b1638SMasahiro Yamada             state->dmax = 1U << len;
702*a194255dSDaniel Boulby             state->flags = 0;               /* indicate zlib header */
703221b1638SMasahiro Yamada             Tracev((stderr, "inflate:   zlib header ok\n"));
704221b1638SMasahiro Yamada             strm->adler = state->check = adler32(0L, Z_NULL, 0);
705221b1638SMasahiro Yamada             state->mode = hold & 0x200 ? DICTID : TYPE;
706221b1638SMasahiro Yamada             INITBITS();
707221b1638SMasahiro Yamada             break;
708221b1638SMasahiro Yamada #ifdef GUNZIP
709221b1638SMasahiro Yamada         case FLAGS:
710221b1638SMasahiro Yamada             NEEDBITS(16);
711221b1638SMasahiro Yamada             state->flags = (int)(hold);
712221b1638SMasahiro Yamada             if ((state->flags & 0xff) != Z_DEFLATED) {
713221b1638SMasahiro Yamada                 strm->msg = (char *)"unknown compression method";
714221b1638SMasahiro Yamada                 state->mode = BAD;
715221b1638SMasahiro Yamada                 break;
716221b1638SMasahiro Yamada             }
717221b1638SMasahiro Yamada             if (state->flags & 0xe000) {
718221b1638SMasahiro Yamada                 strm->msg = (char *)"unknown header flags set";
719221b1638SMasahiro Yamada                 state->mode = BAD;
720221b1638SMasahiro Yamada                 break;
721221b1638SMasahiro Yamada             }
722221b1638SMasahiro Yamada             if (state->head != Z_NULL)
723221b1638SMasahiro Yamada                 state->head->text = (int)((hold >> 8) & 1);
724221b1638SMasahiro Yamada             if ((state->flags & 0x0200) && (state->wrap & 4))
725221b1638SMasahiro Yamada                 CRC2(state->check, hold);
726221b1638SMasahiro Yamada             INITBITS();
727221b1638SMasahiro Yamada             state->mode = TIME;
728*a194255dSDaniel Boulby                 /* fallthrough */
729221b1638SMasahiro Yamada         case TIME:
730221b1638SMasahiro Yamada             NEEDBITS(32);
731221b1638SMasahiro Yamada             if (state->head != Z_NULL)
732221b1638SMasahiro Yamada                 state->head->time = hold;
733221b1638SMasahiro Yamada             if ((state->flags & 0x0200) && (state->wrap & 4))
734221b1638SMasahiro Yamada                 CRC4(state->check, hold);
735221b1638SMasahiro Yamada             INITBITS();
736221b1638SMasahiro Yamada             state->mode = OS;
737*a194255dSDaniel Boulby                 /* fallthrough */
738221b1638SMasahiro Yamada         case OS:
739221b1638SMasahiro Yamada             NEEDBITS(16);
740221b1638SMasahiro Yamada             if (state->head != Z_NULL) {
741221b1638SMasahiro Yamada                 state->head->xflags = (int)(hold & 0xff);
742221b1638SMasahiro Yamada                 state->head->os = (int)(hold >> 8);
743221b1638SMasahiro Yamada             }
744221b1638SMasahiro Yamada             if ((state->flags & 0x0200) && (state->wrap & 4))
745221b1638SMasahiro Yamada                 CRC2(state->check, hold);
746221b1638SMasahiro Yamada             INITBITS();
747221b1638SMasahiro Yamada             state->mode = EXLEN;
748*a194255dSDaniel Boulby                 /* fallthrough */
749221b1638SMasahiro Yamada         case EXLEN:
750221b1638SMasahiro Yamada             if (state->flags & 0x0400) {
751221b1638SMasahiro Yamada                 NEEDBITS(16);
752221b1638SMasahiro Yamada                 state->length = (unsigned)(hold);
753221b1638SMasahiro Yamada                 if (state->head != Z_NULL)
754221b1638SMasahiro Yamada                     state->head->extra_len = (unsigned)hold;
755221b1638SMasahiro Yamada                 if ((state->flags & 0x0200) && (state->wrap & 4))
756221b1638SMasahiro Yamada                     CRC2(state->check, hold);
757221b1638SMasahiro Yamada                 INITBITS();
758221b1638SMasahiro Yamada             }
759221b1638SMasahiro Yamada             else if (state->head != Z_NULL)
760221b1638SMasahiro Yamada                 state->head->extra = Z_NULL;
761221b1638SMasahiro Yamada             state->mode = EXTRA;
762*a194255dSDaniel Boulby                 /* fallthrough */
763221b1638SMasahiro Yamada         case EXTRA:
764221b1638SMasahiro Yamada             if (state->flags & 0x0400) {
765221b1638SMasahiro Yamada                 copy = state->length;
766221b1638SMasahiro Yamada                 if (copy > have) copy = have;
767221b1638SMasahiro Yamada                 if (copy) {
768221b1638SMasahiro Yamada                     if (state->head != Z_NULL &&
769*a194255dSDaniel Boulby                         state->head->extra != Z_NULL &&
770*a194255dSDaniel Boulby                         (len = state->head->extra_len - state->length) <
771*a194255dSDaniel Boulby                             state->head->extra_max) {
772221b1638SMasahiro Yamada                         zmemcpy(state->head->extra + len, next,
773221b1638SMasahiro Yamada                                 len + copy > state->head->extra_max ?
774221b1638SMasahiro Yamada                                 state->head->extra_max - len : copy);
775221b1638SMasahiro Yamada                     }
776221b1638SMasahiro Yamada                     if ((state->flags & 0x0200) && (state->wrap & 4))
777221b1638SMasahiro Yamada                         state->check = crc32(state->check, next, copy);
778221b1638SMasahiro Yamada                     have -= copy;
779221b1638SMasahiro Yamada                     next += copy;
780221b1638SMasahiro Yamada                     state->length -= copy;
781221b1638SMasahiro Yamada                 }
782221b1638SMasahiro Yamada                 if (state->length) goto inf_leave;
783221b1638SMasahiro Yamada             }
784221b1638SMasahiro Yamada             state->length = 0;
785221b1638SMasahiro Yamada             state->mode = NAME;
786*a194255dSDaniel Boulby                 /* fallthrough */
787221b1638SMasahiro Yamada         case NAME:
788221b1638SMasahiro Yamada             if (state->flags & 0x0800) {
789221b1638SMasahiro Yamada                 if (have == 0) goto inf_leave;
790221b1638SMasahiro Yamada                 copy = 0;
791221b1638SMasahiro Yamada                 do {
792221b1638SMasahiro Yamada                     len = (unsigned)(next[copy++]);
793221b1638SMasahiro Yamada                     if (state->head != Z_NULL &&
794221b1638SMasahiro Yamada                             state->head->name != Z_NULL &&
795221b1638SMasahiro Yamada                             state->length < state->head->name_max)
796221b1638SMasahiro Yamada                         state->head->name[state->length++] = (Bytef)len;
797221b1638SMasahiro Yamada                 } while (len && copy < have);
798221b1638SMasahiro Yamada                 if ((state->flags & 0x0200) && (state->wrap & 4))
799221b1638SMasahiro Yamada                     state->check = crc32(state->check, next, copy);
800221b1638SMasahiro Yamada                 have -= copy;
801221b1638SMasahiro Yamada                 next += copy;
802221b1638SMasahiro Yamada                 if (len) goto inf_leave;
803221b1638SMasahiro Yamada             }
804221b1638SMasahiro Yamada             else if (state->head != Z_NULL)
805221b1638SMasahiro Yamada                 state->head->name = Z_NULL;
806221b1638SMasahiro Yamada             state->length = 0;
807221b1638SMasahiro Yamada             state->mode = COMMENT;
808*a194255dSDaniel Boulby                 /* fallthrough */
809221b1638SMasahiro Yamada         case COMMENT:
810221b1638SMasahiro Yamada             if (state->flags & 0x1000) {
811221b1638SMasahiro Yamada                 if (have == 0) goto inf_leave;
812221b1638SMasahiro Yamada                 copy = 0;
813221b1638SMasahiro Yamada                 do {
814221b1638SMasahiro Yamada                     len = (unsigned)(next[copy++]);
815221b1638SMasahiro Yamada                     if (state->head != Z_NULL &&
816221b1638SMasahiro Yamada                             state->head->comment != Z_NULL &&
817221b1638SMasahiro Yamada                             state->length < state->head->comm_max)
818221b1638SMasahiro Yamada                         state->head->comment[state->length++] = (Bytef)len;
819221b1638SMasahiro Yamada                 } while (len && copy < have);
820221b1638SMasahiro Yamada                 if ((state->flags & 0x0200) && (state->wrap & 4))
821221b1638SMasahiro Yamada                     state->check = crc32(state->check, next, copy);
822221b1638SMasahiro Yamada                 have -= copy;
823221b1638SMasahiro Yamada                 next += copy;
824221b1638SMasahiro Yamada                 if (len) goto inf_leave;
825221b1638SMasahiro Yamada             }
826221b1638SMasahiro Yamada             else if (state->head != Z_NULL)
827221b1638SMasahiro Yamada                 state->head->comment = Z_NULL;
828221b1638SMasahiro Yamada             state->mode = HCRC;
829*a194255dSDaniel Boulby                 /* fallthrough */
830221b1638SMasahiro Yamada         case HCRC:
831221b1638SMasahiro Yamada             if (state->flags & 0x0200) {
832221b1638SMasahiro Yamada                 NEEDBITS(16);
833221b1638SMasahiro Yamada                 if ((state->wrap & 4) && hold != (state->check & 0xffff)) {
834221b1638SMasahiro Yamada                     strm->msg = (char *)"header crc mismatch";
835221b1638SMasahiro Yamada                     state->mode = BAD;
836221b1638SMasahiro Yamada                     break;
837221b1638SMasahiro Yamada                 }
838221b1638SMasahiro Yamada                 INITBITS();
839221b1638SMasahiro Yamada             }
840221b1638SMasahiro Yamada             if (state->head != Z_NULL) {
841221b1638SMasahiro Yamada                 state->head->hcrc = (int)((state->flags >> 9) & 1);
842221b1638SMasahiro Yamada                 state->head->done = 1;
843221b1638SMasahiro Yamada             }
844221b1638SMasahiro Yamada             strm->adler = state->check = crc32(0L, Z_NULL, 0);
845221b1638SMasahiro Yamada             state->mode = TYPE;
846221b1638SMasahiro Yamada             break;
847221b1638SMasahiro Yamada #endif
848221b1638SMasahiro Yamada         case DICTID:
849221b1638SMasahiro Yamada             NEEDBITS(32);
850221b1638SMasahiro Yamada             strm->adler = state->check = ZSWAP32(hold);
851221b1638SMasahiro Yamada             INITBITS();
852221b1638SMasahiro Yamada             state->mode = DICT;
853*a194255dSDaniel Boulby                 /* fallthrough */
854221b1638SMasahiro Yamada         case DICT:
855221b1638SMasahiro Yamada             if (state->havedict == 0) {
856221b1638SMasahiro Yamada                 RESTORE();
857221b1638SMasahiro Yamada                 return Z_NEED_DICT;
858221b1638SMasahiro Yamada             }
859221b1638SMasahiro Yamada             strm->adler = state->check = adler32(0L, Z_NULL, 0);
860221b1638SMasahiro Yamada             state->mode = TYPE;
861*a194255dSDaniel Boulby                 /* fallthrough */
862221b1638SMasahiro Yamada         case TYPE:
863221b1638SMasahiro Yamada             if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
864*a194255dSDaniel Boulby                 /* fallthrough */
865221b1638SMasahiro Yamada         case TYPEDO:
866221b1638SMasahiro Yamada             if (state->last) {
867221b1638SMasahiro Yamada                 BYTEBITS();
868221b1638SMasahiro Yamada                 state->mode = CHECK;
869221b1638SMasahiro Yamada                 break;
870221b1638SMasahiro Yamada             }
871221b1638SMasahiro Yamada             NEEDBITS(3);
872221b1638SMasahiro Yamada             state->last = BITS(1);
873221b1638SMasahiro Yamada             DROPBITS(1);
874221b1638SMasahiro Yamada             switch (BITS(2)) {
875221b1638SMasahiro Yamada             case 0:                             /* stored block */
876221b1638SMasahiro Yamada                 Tracev((stderr, "inflate:     stored block%s\n",
877221b1638SMasahiro Yamada                         state->last ? " (last)" : ""));
878221b1638SMasahiro Yamada                 state->mode = STORED;
879221b1638SMasahiro Yamada                 break;
880221b1638SMasahiro Yamada             case 1:                             /* fixed block */
881221b1638SMasahiro Yamada                 fixedtables(state);
882221b1638SMasahiro Yamada                 Tracev((stderr, "inflate:     fixed codes block%s\n",
883221b1638SMasahiro Yamada                         state->last ? " (last)" : ""));
884221b1638SMasahiro Yamada                 state->mode = LEN_;             /* decode codes */
885221b1638SMasahiro Yamada                 if (flush == Z_TREES) {
886221b1638SMasahiro Yamada                     DROPBITS(2);
887221b1638SMasahiro Yamada                     goto inf_leave;
888221b1638SMasahiro Yamada                 }
889221b1638SMasahiro Yamada                 break;
890221b1638SMasahiro Yamada             case 2:                             /* dynamic block */
891221b1638SMasahiro Yamada                 Tracev((stderr, "inflate:     dynamic codes block%s\n",
892221b1638SMasahiro Yamada                         state->last ? " (last)" : ""));
893221b1638SMasahiro Yamada                 state->mode = TABLE;
894221b1638SMasahiro Yamada                 break;
895221b1638SMasahiro Yamada             case 3:
896221b1638SMasahiro Yamada                 strm->msg = (char *)"invalid block type";
897221b1638SMasahiro Yamada                 state->mode = BAD;
898221b1638SMasahiro Yamada             }
899221b1638SMasahiro Yamada             DROPBITS(2);
900221b1638SMasahiro Yamada             break;
901221b1638SMasahiro Yamada         case STORED:
902221b1638SMasahiro Yamada             BYTEBITS();                         /* go to byte boundary */
903221b1638SMasahiro Yamada             NEEDBITS(32);
904221b1638SMasahiro Yamada             if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
905221b1638SMasahiro Yamada                 strm->msg = (char *)"invalid stored block lengths";
906221b1638SMasahiro Yamada                 state->mode = BAD;
907221b1638SMasahiro Yamada                 break;
908221b1638SMasahiro Yamada             }
909221b1638SMasahiro Yamada             state->length = (unsigned)hold & 0xffff;
910221b1638SMasahiro Yamada             Tracev((stderr, "inflate:       stored length %u\n",
911221b1638SMasahiro Yamada                     state->length));
912221b1638SMasahiro Yamada             INITBITS();
913221b1638SMasahiro Yamada             state->mode = COPY_;
914221b1638SMasahiro Yamada             if (flush == Z_TREES) goto inf_leave;
915*a194255dSDaniel Boulby                 /* fallthrough */
916221b1638SMasahiro Yamada         case COPY_:
917221b1638SMasahiro Yamada             state->mode = COPY;
918*a194255dSDaniel Boulby                 /* fallthrough */
919221b1638SMasahiro Yamada         case COPY:
920221b1638SMasahiro Yamada             copy = state->length;
921221b1638SMasahiro Yamada             if (copy) {
922221b1638SMasahiro Yamada                 if (copy > have) copy = have;
923221b1638SMasahiro Yamada                 if (copy > left) copy = left;
924221b1638SMasahiro Yamada                 if (copy == 0) goto inf_leave;
925221b1638SMasahiro Yamada                 zmemcpy(put, next, copy);
926221b1638SMasahiro Yamada                 have -= copy;
927221b1638SMasahiro Yamada                 next += copy;
928221b1638SMasahiro Yamada                 left -= copy;
929221b1638SMasahiro Yamada                 put += copy;
930221b1638SMasahiro Yamada                 state->length -= copy;
931221b1638SMasahiro Yamada                 break;
932221b1638SMasahiro Yamada             }
933221b1638SMasahiro Yamada             Tracev((stderr, "inflate:       stored end\n"));
934221b1638SMasahiro Yamada             state->mode = TYPE;
935221b1638SMasahiro Yamada             break;
936221b1638SMasahiro Yamada         case TABLE:
937221b1638SMasahiro Yamada             NEEDBITS(14);
938221b1638SMasahiro Yamada             state->nlen = BITS(5) + 257;
939221b1638SMasahiro Yamada             DROPBITS(5);
940221b1638SMasahiro Yamada             state->ndist = BITS(5) + 1;
941221b1638SMasahiro Yamada             DROPBITS(5);
942221b1638SMasahiro Yamada             state->ncode = BITS(4) + 4;
943221b1638SMasahiro Yamada             DROPBITS(4);
944221b1638SMasahiro Yamada #ifndef PKZIP_BUG_WORKAROUND
945221b1638SMasahiro Yamada             if (state->nlen > 286 || state->ndist > 30) {
946221b1638SMasahiro Yamada                 strm->msg = (char *)"too many length or distance symbols";
947221b1638SMasahiro Yamada                 state->mode = BAD;
948221b1638SMasahiro Yamada                 break;
949221b1638SMasahiro Yamada             }
950221b1638SMasahiro Yamada #endif
951221b1638SMasahiro Yamada             Tracev((stderr, "inflate:       table sizes ok\n"));
952221b1638SMasahiro Yamada             state->have = 0;
953221b1638SMasahiro Yamada             state->mode = LENLENS;
954*a194255dSDaniel Boulby                 /* fallthrough */
955221b1638SMasahiro Yamada         case LENLENS:
956221b1638SMasahiro Yamada             while (state->have < state->ncode) {
957221b1638SMasahiro Yamada                 NEEDBITS(3);
958221b1638SMasahiro Yamada                 state->lens[order[state->have++]] = (unsigned short)BITS(3);
959221b1638SMasahiro Yamada                 DROPBITS(3);
960221b1638SMasahiro Yamada             }
961221b1638SMasahiro Yamada             while (state->have < 19)
962221b1638SMasahiro Yamada                 state->lens[order[state->have++]] = 0;
963221b1638SMasahiro Yamada             state->next = state->codes;
964221b1638SMasahiro Yamada             state->lencode = (const code FAR *)(state->next);
965221b1638SMasahiro Yamada             state->lenbits = 7;
966221b1638SMasahiro Yamada             ret = inflate_table(CODES, state->lens, 19, &(state->next),
967221b1638SMasahiro Yamada                                 &(state->lenbits), state->work);
968221b1638SMasahiro Yamada             if (ret) {
969221b1638SMasahiro Yamada                 strm->msg = (char *)"invalid code lengths set";
970221b1638SMasahiro Yamada                 state->mode = BAD;
971221b1638SMasahiro Yamada                 break;
972221b1638SMasahiro Yamada             }
973221b1638SMasahiro Yamada             Tracev((stderr, "inflate:       code lengths ok\n"));
974221b1638SMasahiro Yamada             state->have = 0;
975221b1638SMasahiro Yamada             state->mode = CODELENS;
976*a194255dSDaniel Boulby                 /* fallthrough */
977221b1638SMasahiro Yamada         case CODELENS:
978221b1638SMasahiro Yamada             while (state->have < state->nlen + state->ndist) {
979221b1638SMasahiro Yamada                 for (;;) {
980221b1638SMasahiro Yamada                     here = state->lencode[BITS(state->lenbits)];
981221b1638SMasahiro Yamada                     if ((unsigned)(here.bits) <= bits) break;
982221b1638SMasahiro Yamada                     PULLBYTE();
983221b1638SMasahiro Yamada                 }
984221b1638SMasahiro Yamada                 if (here.val < 16) {
985221b1638SMasahiro Yamada                     DROPBITS(here.bits);
986221b1638SMasahiro Yamada                     state->lens[state->have++] = here.val;
987221b1638SMasahiro Yamada                 }
988221b1638SMasahiro Yamada                 else {
989221b1638SMasahiro Yamada                     if (here.val == 16) {
990221b1638SMasahiro Yamada                         NEEDBITS(here.bits + 2);
991221b1638SMasahiro Yamada                         DROPBITS(here.bits);
992221b1638SMasahiro Yamada                         if (state->have == 0) {
993221b1638SMasahiro Yamada                             strm->msg = (char *)"invalid bit length repeat";
994221b1638SMasahiro Yamada                             state->mode = BAD;
995221b1638SMasahiro Yamada                             break;
996221b1638SMasahiro Yamada                         }
997221b1638SMasahiro Yamada                         len = state->lens[state->have - 1];
998221b1638SMasahiro Yamada                         copy = 3 + BITS(2);
999221b1638SMasahiro Yamada                         DROPBITS(2);
1000221b1638SMasahiro Yamada                     }
1001221b1638SMasahiro Yamada                     else if (here.val == 17) {
1002221b1638SMasahiro Yamada                         NEEDBITS(here.bits + 3);
1003221b1638SMasahiro Yamada                         DROPBITS(here.bits);
1004221b1638SMasahiro Yamada                         len = 0;
1005221b1638SMasahiro Yamada                         copy = 3 + BITS(3);
1006221b1638SMasahiro Yamada                         DROPBITS(3);
1007221b1638SMasahiro Yamada                     }
1008221b1638SMasahiro Yamada                     else {
1009221b1638SMasahiro Yamada                         NEEDBITS(here.bits + 7);
1010221b1638SMasahiro Yamada                         DROPBITS(here.bits);
1011221b1638SMasahiro Yamada                         len = 0;
1012221b1638SMasahiro Yamada                         copy = 11 + BITS(7);
1013221b1638SMasahiro Yamada                         DROPBITS(7);
1014221b1638SMasahiro Yamada                     }
1015221b1638SMasahiro Yamada                     if (state->have + copy > state->nlen + state->ndist) {
1016221b1638SMasahiro Yamada                         strm->msg = (char *)"invalid bit length repeat";
1017221b1638SMasahiro Yamada                         state->mode = BAD;
1018221b1638SMasahiro Yamada                         break;
1019221b1638SMasahiro Yamada                     }
1020221b1638SMasahiro Yamada                     while (copy--)
1021221b1638SMasahiro Yamada                         state->lens[state->have++] = (unsigned short)len;
1022221b1638SMasahiro Yamada                 }
1023221b1638SMasahiro Yamada             }
1024221b1638SMasahiro Yamada 
1025221b1638SMasahiro Yamada             /* handle error breaks in while */
1026221b1638SMasahiro Yamada             if (state->mode == BAD) break;
1027221b1638SMasahiro Yamada 
1028221b1638SMasahiro Yamada             /* check for end-of-block code (better have one) */
1029221b1638SMasahiro Yamada             if (state->lens[256] == 0) {
1030221b1638SMasahiro Yamada                 strm->msg = (char *)"invalid code -- missing end-of-block";
1031221b1638SMasahiro Yamada                 state->mode = BAD;
1032221b1638SMasahiro Yamada                 break;
1033221b1638SMasahiro Yamada             }
1034221b1638SMasahiro Yamada 
1035221b1638SMasahiro Yamada             /* build code tables -- note: do not change the lenbits or distbits
1036221b1638SMasahiro Yamada                values here (9 and 6) without reading the comments in inftrees.h
1037221b1638SMasahiro Yamada                concerning the ENOUGH constants, which depend on those values */
1038221b1638SMasahiro Yamada             state->next = state->codes;
1039221b1638SMasahiro Yamada             state->lencode = (const code FAR *)(state->next);
1040221b1638SMasahiro Yamada             state->lenbits = 9;
1041221b1638SMasahiro Yamada             ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
1042221b1638SMasahiro Yamada                                 &(state->lenbits), state->work);
1043221b1638SMasahiro Yamada             if (ret) {
1044221b1638SMasahiro Yamada                 strm->msg = (char *)"invalid literal/lengths set";
1045221b1638SMasahiro Yamada                 state->mode = BAD;
1046221b1638SMasahiro Yamada                 break;
1047221b1638SMasahiro Yamada             }
1048221b1638SMasahiro Yamada             state->distcode = (const code FAR *)(state->next);
1049221b1638SMasahiro Yamada             state->distbits = 6;
1050221b1638SMasahiro Yamada             ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
1051221b1638SMasahiro Yamada                             &(state->next), &(state->distbits), state->work);
1052221b1638SMasahiro Yamada             if (ret) {
1053221b1638SMasahiro Yamada                 strm->msg = (char *)"invalid distances set";
1054221b1638SMasahiro Yamada                 state->mode = BAD;
1055221b1638SMasahiro Yamada                 break;
1056221b1638SMasahiro Yamada             }
1057221b1638SMasahiro Yamada             Tracev((stderr, "inflate:       codes ok\n"));
1058221b1638SMasahiro Yamada             state->mode = LEN_;
1059221b1638SMasahiro Yamada             if (flush == Z_TREES) goto inf_leave;
1060*a194255dSDaniel Boulby                 /* fallthrough */
1061221b1638SMasahiro Yamada         case LEN_:
1062221b1638SMasahiro Yamada             state->mode = LEN;
1063*a194255dSDaniel Boulby                 /* fallthrough */
1064221b1638SMasahiro Yamada         case LEN:
1065221b1638SMasahiro Yamada             if (have >= 6 && left >= 258) {
1066221b1638SMasahiro Yamada                 RESTORE();
1067221b1638SMasahiro Yamada                 inflate_fast(strm, out);
1068221b1638SMasahiro Yamada                 LOAD();
1069221b1638SMasahiro Yamada                 if (state->mode == TYPE)
1070221b1638SMasahiro Yamada                     state->back = -1;
1071221b1638SMasahiro Yamada                 break;
1072221b1638SMasahiro Yamada             }
1073221b1638SMasahiro Yamada             state->back = 0;
1074221b1638SMasahiro Yamada             for (;;) {
1075221b1638SMasahiro Yamada                 here = state->lencode[BITS(state->lenbits)];
1076221b1638SMasahiro Yamada                 if ((unsigned)(here.bits) <= bits) break;
1077221b1638SMasahiro Yamada                 PULLBYTE();
1078221b1638SMasahiro Yamada             }
1079221b1638SMasahiro Yamada             if (here.op && (here.op & 0xf0) == 0) {
1080221b1638SMasahiro Yamada                 last = here;
1081221b1638SMasahiro Yamada                 for (;;) {
1082221b1638SMasahiro Yamada                     here = state->lencode[last.val +
1083221b1638SMasahiro Yamada                             (BITS(last.bits + last.op) >> last.bits)];
1084221b1638SMasahiro Yamada                     if ((unsigned)(last.bits + here.bits) <= bits) break;
1085221b1638SMasahiro Yamada                     PULLBYTE();
1086221b1638SMasahiro Yamada                 }
1087221b1638SMasahiro Yamada                 DROPBITS(last.bits);
1088221b1638SMasahiro Yamada                 state->back += last.bits;
1089221b1638SMasahiro Yamada             }
1090221b1638SMasahiro Yamada             DROPBITS(here.bits);
1091221b1638SMasahiro Yamada             state->back += here.bits;
1092221b1638SMasahiro Yamada             state->length = (unsigned)here.val;
1093221b1638SMasahiro Yamada             if ((int)(here.op) == 0) {
1094221b1638SMasahiro Yamada                 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
1095221b1638SMasahiro Yamada                         "inflate:         literal '%c'\n" :
1096221b1638SMasahiro Yamada                         "inflate:         literal 0x%02x\n", here.val));
1097221b1638SMasahiro Yamada                 state->mode = LIT;
1098221b1638SMasahiro Yamada                 break;
1099221b1638SMasahiro Yamada             }
1100221b1638SMasahiro Yamada             if (here.op & 32) {
1101221b1638SMasahiro Yamada                 Tracevv((stderr, "inflate:         end of block\n"));
1102221b1638SMasahiro Yamada                 state->back = -1;
1103221b1638SMasahiro Yamada                 state->mode = TYPE;
1104221b1638SMasahiro Yamada                 break;
1105221b1638SMasahiro Yamada             }
1106221b1638SMasahiro Yamada             if (here.op & 64) {
1107221b1638SMasahiro Yamada                 strm->msg = (char *)"invalid literal/length code";
1108221b1638SMasahiro Yamada                 state->mode = BAD;
1109221b1638SMasahiro Yamada                 break;
1110221b1638SMasahiro Yamada             }
1111221b1638SMasahiro Yamada             state->extra = (unsigned)(here.op) & 15;
1112221b1638SMasahiro Yamada             state->mode = LENEXT;
1113*a194255dSDaniel Boulby                 /* fallthrough */
1114221b1638SMasahiro Yamada         case LENEXT:
1115221b1638SMasahiro Yamada             if (state->extra) {
1116221b1638SMasahiro Yamada                 NEEDBITS(state->extra);
1117221b1638SMasahiro Yamada                 state->length += BITS(state->extra);
1118221b1638SMasahiro Yamada                 DROPBITS(state->extra);
1119221b1638SMasahiro Yamada                 state->back += state->extra;
1120221b1638SMasahiro Yamada             }
1121221b1638SMasahiro Yamada             Tracevv((stderr, "inflate:         length %u\n", state->length));
1122221b1638SMasahiro Yamada             state->was = state->length;
1123221b1638SMasahiro Yamada             state->mode = DIST;
1124*a194255dSDaniel Boulby                 /* fallthrough */
1125221b1638SMasahiro Yamada         case DIST:
1126221b1638SMasahiro Yamada             for (;;) {
1127221b1638SMasahiro Yamada                 here = state->distcode[BITS(state->distbits)];
1128221b1638SMasahiro Yamada                 if ((unsigned)(here.bits) <= bits) break;
1129221b1638SMasahiro Yamada                 PULLBYTE();
1130221b1638SMasahiro Yamada             }
1131221b1638SMasahiro Yamada             if ((here.op & 0xf0) == 0) {
1132221b1638SMasahiro Yamada                 last = here;
1133221b1638SMasahiro Yamada                 for (;;) {
1134221b1638SMasahiro Yamada                     here = state->distcode[last.val +
1135221b1638SMasahiro Yamada                             (BITS(last.bits + last.op) >> last.bits)];
1136221b1638SMasahiro Yamada                     if ((unsigned)(last.bits + here.bits) <= bits) break;
1137221b1638SMasahiro Yamada                     PULLBYTE();
1138221b1638SMasahiro Yamada                 }
1139221b1638SMasahiro Yamada                 DROPBITS(last.bits);
1140221b1638SMasahiro Yamada                 state->back += last.bits;
1141221b1638SMasahiro Yamada             }
1142221b1638SMasahiro Yamada             DROPBITS(here.bits);
1143221b1638SMasahiro Yamada             state->back += here.bits;
1144221b1638SMasahiro Yamada             if (here.op & 64) {
1145221b1638SMasahiro Yamada                 strm->msg = (char *)"invalid distance code";
1146221b1638SMasahiro Yamada                 state->mode = BAD;
1147221b1638SMasahiro Yamada                 break;
1148221b1638SMasahiro Yamada             }
1149221b1638SMasahiro Yamada             state->offset = (unsigned)here.val;
1150221b1638SMasahiro Yamada             state->extra = (unsigned)(here.op) & 15;
1151221b1638SMasahiro Yamada             state->mode = DISTEXT;
1152*a194255dSDaniel Boulby                 /* fallthrough */
1153221b1638SMasahiro Yamada         case DISTEXT:
1154221b1638SMasahiro Yamada             if (state->extra) {
1155221b1638SMasahiro Yamada                 NEEDBITS(state->extra);
1156221b1638SMasahiro Yamada                 state->offset += BITS(state->extra);
1157221b1638SMasahiro Yamada                 DROPBITS(state->extra);
1158221b1638SMasahiro Yamada                 state->back += state->extra;
1159221b1638SMasahiro Yamada             }
1160221b1638SMasahiro Yamada #ifdef INFLATE_STRICT
1161221b1638SMasahiro Yamada             if (state->offset > state->dmax) {
1162221b1638SMasahiro Yamada                 strm->msg = (char *)"invalid distance too far back";
1163221b1638SMasahiro Yamada                 state->mode = BAD;
1164221b1638SMasahiro Yamada                 break;
1165221b1638SMasahiro Yamada             }
1166221b1638SMasahiro Yamada #endif
1167221b1638SMasahiro Yamada             Tracevv((stderr, "inflate:         distance %u\n", state->offset));
1168221b1638SMasahiro Yamada             state->mode = MATCH;
1169*a194255dSDaniel Boulby                 /* fallthrough */
1170221b1638SMasahiro Yamada         case MATCH:
1171221b1638SMasahiro Yamada             if (left == 0) goto inf_leave;
1172221b1638SMasahiro Yamada             copy = out - left;
1173221b1638SMasahiro Yamada             if (state->offset > copy) {         /* copy from window */
1174221b1638SMasahiro Yamada                 copy = state->offset - copy;
1175221b1638SMasahiro Yamada                 if (copy > state->whave) {
1176221b1638SMasahiro Yamada                     if (state->sane) {
1177221b1638SMasahiro Yamada                         strm->msg = (char *)"invalid distance too far back";
1178221b1638SMasahiro Yamada                         state->mode = BAD;
1179221b1638SMasahiro Yamada                         break;
1180221b1638SMasahiro Yamada                     }
1181221b1638SMasahiro Yamada #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
1182221b1638SMasahiro Yamada                     Trace((stderr, "inflate.c too far\n"));
1183221b1638SMasahiro Yamada                     copy -= state->whave;
1184221b1638SMasahiro Yamada                     if (copy > state->length) copy = state->length;
1185221b1638SMasahiro Yamada                     if (copy > left) copy = left;
1186221b1638SMasahiro Yamada                     left -= copy;
1187221b1638SMasahiro Yamada                     state->length -= copy;
1188221b1638SMasahiro Yamada                     do {
1189221b1638SMasahiro Yamada                         *put++ = 0;
1190221b1638SMasahiro Yamada                     } while (--copy);
1191221b1638SMasahiro Yamada                     if (state->length == 0) state->mode = LEN;
1192221b1638SMasahiro Yamada                     break;
1193221b1638SMasahiro Yamada #endif
1194221b1638SMasahiro Yamada                 }
1195221b1638SMasahiro Yamada                 if (copy > state->wnext) {
1196221b1638SMasahiro Yamada                     copy -= state->wnext;
1197221b1638SMasahiro Yamada                     from = state->window + (state->wsize - copy);
1198221b1638SMasahiro Yamada                 }
1199221b1638SMasahiro Yamada                 else
1200221b1638SMasahiro Yamada                     from = state->window + (state->wnext - copy);
1201221b1638SMasahiro Yamada                 if (copy > state->length) copy = state->length;
1202221b1638SMasahiro Yamada             }
1203221b1638SMasahiro Yamada             else {                              /* copy from output */
1204221b1638SMasahiro Yamada                 from = put - state->offset;
1205221b1638SMasahiro Yamada                 copy = state->length;
1206221b1638SMasahiro Yamada             }
1207221b1638SMasahiro Yamada             if (copy > left) copy = left;
1208221b1638SMasahiro Yamada             left -= copy;
1209221b1638SMasahiro Yamada             state->length -= copy;
1210221b1638SMasahiro Yamada             do {
1211221b1638SMasahiro Yamada                 *put++ = *from++;
1212221b1638SMasahiro Yamada             } while (--copy);
1213221b1638SMasahiro Yamada             if (state->length == 0) state->mode = LEN;
1214221b1638SMasahiro Yamada             break;
1215221b1638SMasahiro Yamada         case LIT:
1216221b1638SMasahiro Yamada             if (left == 0) goto inf_leave;
1217221b1638SMasahiro Yamada             *put++ = (unsigned char)(state->length);
1218221b1638SMasahiro Yamada             left--;
1219221b1638SMasahiro Yamada             state->mode = LEN;
1220221b1638SMasahiro Yamada             break;
1221221b1638SMasahiro Yamada         case CHECK:
1222221b1638SMasahiro Yamada             if (state->wrap) {
1223221b1638SMasahiro Yamada                 NEEDBITS(32);
1224221b1638SMasahiro Yamada                 out -= left;
1225221b1638SMasahiro Yamada                 strm->total_out += out;
1226221b1638SMasahiro Yamada                 state->total += out;
1227221b1638SMasahiro Yamada                 if ((state->wrap & 4) && out)
1228221b1638SMasahiro Yamada                     strm->adler = state->check =
1229*a194255dSDaniel Boulby                         UPDATE_CHECK(state->check, put - out, out);
1230221b1638SMasahiro Yamada                 out = left;
1231221b1638SMasahiro Yamada                 if ((state->wrap & 4) && (
1232221b1638SMasahiro Yamada #ifdef GUNZIP
1233221b1638SMasahiro Yamada                      state->flags ? hold :
1234221b1638SMasahiro Yamada #endif
1235221b1638SMasahiro Yamada                      ZSWAP32(hold)) != state->check) {
1236221b1638SMasahiro Yamada                     strm->msg = (char *)"incorrect data check";
1237221b1638SMasahiro Yamada                     state->mode = BAD;
1238221b1638SMasahiro Yamada                     break;
1239221b1638SMasahiro Yamada                 }
1240221b1638SMasahiro Yamada                 INITBITS();
1241221b1638SMasahiro Yamada                 Tracev((stderr, "inflate:   check matches trailer\n"));
1242221b1638SMasahiro Yamada             }
1243221b1638SMasahiro Yamada #ifdef GUNZIP
1244221b1638SMasahiro Yamada             state->mode = LENGTH;
1245*a194255dSDaniel Boulby                 /* fallthrough */
1246221b1638SMasahiro Yamada         case LENGTH:
1247221b1638SMasahiro Yamada             if (state->wrap && state->flags) {
1248221b1638SMasahiro Yamada                 NEEDBITS(32);
1249*a194255dSDaniel Boulby                 if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) {
1250221b1638SMasahiro Yamada                     strm->msg = (char *)"incorrect length check";
1251221b1638SMasahiro Yamada                     state->mode = BAD;
1252221b1638SMasahiro Yamada                     break;
1253221b1638SMasahiro Yamada                 }
1254221b1638SMasahiro Yamada                 INITBITS();
1255221b1638SMasahiro Yamada                 Tracev((stderr, "inflate:   length matches trailer\n"));
1256221b1638SMasahiro Yamada             }
1257221b1638SMasahiro Yamada #endif
1258221b1638SMasahiro Yamada             state->mode = DONE;
1259*a194255dSDaniel Boulby                 /* fallthrough */
1260221b1638SMasahiro Yamada         case DONE:
1261221b1638SMasahiro Yamada             ret = Z_STREAM_END;
1262221b1638SMasahiro Yamada             goto inf_leave;
1263221b1638SMasahiro Yamada         case BAD:
1264221b1638SMasahiro Yamada             ret = Z_DATA_ERROR;
1265221b1638SMasahiro Yamada             goto inf_leave;
1266221b1638SMasahiro Yamada         case MEM:
1267221b1638SMasahiro Yamada             return Z_MEM_ERROR;
1268221b1638SMasahiro Yamada         case SYNC:
1269*a194255dSDaniel Boulby                 /* fallthrough */
1270221b1638SMasahiro Yamada         default:
1271221b1638SMasahiro Yamada             return Z_STREAM_ERROR;
1272221b1638SMasahiro Yamada         }
1273221b1638SMasahiro Yamada 
1274221b1638SMasahiro Yamada     /*
1275221b1638SMasahiro Yamada        Return from inflate(), updating the total counts and the check value.
1276221b1638SMasahiro Yamada        If there was no progress during the inflate() call, return a buffer
1277221b1638SMasahiro Yamada        error.  Call updatewindow() to create and/or update the window state.
1278221b1638SMasahiro Yamada        Note: a memory error from inflate() is non-recoverable.
1279221b1638SMasahiro Yamada      */
1280221b1638SMasahiro Yamada   inf_leave:
1281221b1638SMasahiro Yamada     RESTORE();
1282221b1638SMasahiro Yamada     if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
1283221b1638SMasahiro Yamada             (state->mode < CHECK || flush != Z_FINISH)))
1284221b1638SMasahiro Yamada         if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
1285221b1638SMasahiro Yamada             state->mode = MEM;
1286221b1638SMasahiro Yamada             return Z_MEM_ERROR;
1287221b1638SMasahiro Yamada         }
1288221b1638SMasahiro Yamada     in -= strm->avail_in;
1289221b1638SMasahiro Yamada     out -= strm->avail_out;
1290221b1638SMasahiro Yamada     strm->total_in += in;
1291221b1638SMasahiro Yamada     strm->total_out += out;
1292221b1638SMasahiro Yamada     state->total += out;
1293221b1638SMasahiro Yamada     if ((state->wrap & 4) && out)
1294221b1638SMasahiro Yamada         strm->adler = state->check =
1295*a194255dSDaniel Boulby             UPDATE_CHECK(state->check, strm->next_out - out, out);
1296221b1638SMasahiro Yamada     strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
1297221b1638SMasahiro Yamada                       (state->mode == TYPE ? 128 : 0) +
1298221b1638SMasahiro Yamada                       (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
1299221b1638SMasahiro Yamada     if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
1300221b1638SMasahiro Yamada         ret = Z_BUF_ERROR;
1301221b1638SMasahiro Yamada     return ret;
1302221b1638SMasahiro Yamada }
1303221b1638SMasahiro Yamada 
1304221b1638SMasahiro Yamada int ZEXPORT inflateEnd(strm)
1305221b1638SMasahiro Yamada z_streamp strm;
1306221b1638SMasahiro Yamada {
1307221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1308221b1638SMasahiro Yamada     if (inflateStateCheck(strm))
1309221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
1310221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1311221b1638SMasahiro Yamada     if (state->window != Z_NULL) ZFREE(strm, state->window);
1312221b1638SMasahiro Yamada     ZFREE(strm, strm->state);
1313221b1638SMasahiro Yamada     strm->state = Z_NULL;
1314221b1638SMasahiro Yamada     Tracev((stderr, "inflate: end\n"));
1315221b1638SMasahiro Yamada     return Z_OK;
1316221b1638SMasahiro Yamada }
1317221b1638SMasahiro Yamada 
1318221b1638SMasahiro Yamada int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
1319221b1638SMasahiro Yamada z_streamp strm;
1320221b1638SMasahiro Yamada Bytef *dictionary;
1321221b1638SMasahiro Yamada uInt *dictLength;
1322221b1638SMasahiro Yamada {
1323221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1324221b1638SMasahiro Yamada 
1325221b1638SMasahiro Yamada     /* check state */
1326221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1327221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1328221b1638SMasahiro Yamada 
1329221b1638SMasahiro Yamada     /* copy dictionary */
1330221b1638SMasahiro Yamada     if (state->whave && dictionary != Z_NULL) {
1331221b1638SMasahiro Yamada         zmemcpy(dictionary, state->window + state->wnext,
1332221b1638SMasahiro Yamada                 state->whave - state->wnext);
1333221b1638SMasahiro Yamada         zmemcpy(dictionary + state->whave - state->wnext,
1334221b1638SMasahiro Yamada                 state->window, state->wnext);
1335221b1638SMasahiro Yamada     }
1336221b1638SMasahiro Yamada     if (dictLength != Z_NULL)
1337221b1638SMasahiro Yamada         *dictLength = state->whave;
1338221b1638SMasahiro Yamada     return Z_OK;
1339221b1638SMasahiro Yamada }
1340221b1638SMasahiro Yamada 
1341221b1638SMasahiro Yamada int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
1342221b1638SMasahiro Yamada z_streamp strm;
1343221b1638SMasahiro Yamada const Bytef *dictionary;
1344221b1638SMasahiro Yamada uInt dictLength;
1345221b1638SMasahiro Yamada {
1346221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1347221b1638SMasahiro Yamada     unsigned long dictid;
1348221b1638SMasahiro Yamada     int ret;
1349221b1638SMasahiro Yamada 
1350221b1638SMasahiro Yamada     /* check state */
1351221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1352221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1353221b1638SMasahiro Yamada     if (state->wrap != 0 && state->mode != DICT)
1354221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
1355221b1638SMasahiro Yamada 
1356221b1638SMasahiro Yamada     /* check for correct dictionary identifier */
1357221b1638SMasahiro Yamada     if (state->mode == DICT) {
1358221b1638SMasahiro Yamada         dictid = adler32(0L, Z_NULL, 0);
1359221b1638SMasahiro Yamada         dictid = adler32(dictid, dictionary, dictLength);
1360221b1638SMasahiro Yamada         if (dictid != state->check)
1361221b1638SMasahiro Yamada             return Z_DATA_ERROR;
1362221b1638SMasahiro Yamada     }
1363221b1638SMasahiro Yamada 
1364221b1638SMasahiro Yamada     /* copy dictionary to window using updatewindow(), which will amend the
1365221b1638SMasahiro Yamada        existing dictionary if appropriate */
1366221b1638SMasahiro Yamada     ret = updatewindow(strm, dictionary + dictLength, dictLength);
1367221b1638SMasahiro Yamada     if (ret) {
1368221b1638SMasahiro Yamada         state->mode = MEM;
1369221b1638SMasahiro Yamada         return Z_MEM_ERROR;
1370221b1638SMasahiro Yamada     }
1371221b1638SMasahiro Yamada     state->havedict = 1;
1372221b1638SMasahiro Yamada     Tracev((stderr, "inflate:   dictionary set\n"));
1373221b1638SMasahiro Yamada     return Z_OK;
1374221b1638SMasahiro Yamada }
1375221b1638SMasahiro Yamada 
1376221b1638SMasahiro Yamada int ZEXPORT inflateGetHeader(strm, head)
1377221b1638SMasahiro Yamada z_streamp strm;
1378221b1638SMasahiro Yamada gz_headerp head;
1379221b1638SMasahiro Yamada {
1380221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1381221b1638SMasahiro Yamada 
1382221b1638SMasahiro Yamada     /* check state */
1383221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1384221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1385221b1638SMasahiro Yamada     if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
1386221b1638SMasahiro Yamada 
1387221b1638SMasahiro Yamada     /* save header structure */
1388221b1638SMasahiro Yamada     state->head = head;
1389221b1638SMasahiro Yamada     head->done = 0;
1390221b1638SMasahiro Yamada     return Z_OK;
1391221b1638SMasahiro Yamada }
1392221b1638SMasahiro Yamada 
1393221b1638SMasahiro Yamada /*
1394221b1638SMasahiro Yamada    Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
1395221b1638SMasahiro Yamada    or when out of input.  When called, *have is the number of pattern bytes
1396221b1638SMasahiro Yamada    found in order so far, in 0..3.  On return *have is updated to the new
1397221b1638SMasahiro Yamada    state.  If on return *have equals four, then the pattern was found and the
1398221b1638SMasahiro Yamada    return value is how many bytes were read including the last byte of the
1399221b1638SMasahiro Yamada    pattern.  If *have is less than four, then the pattern has not been found
1400221b1638SMasahiro Yamada    yet and the return value is len.  In the latter case, syncsearch() can be
1401221b1638SMasahiro Yamada    called again with more data and the *have state.  *have is initialized to
1402221b1638SMasahiro Yamada    zero for the first call.
1403221b1638SMasahiro Yamada  */
1404221b1638SMasahiro Yamada local unsigned syncsearch(have, buf, len)
1405221b1638SMasahiro Yamada unsigned FAR *have;
1406221b1638SMasahiro Yamada const unsigned char FAR *buf;
1407221b1638SMasahiro Yamada unsigned len;
1408221b1638SMasahiro Yamada {
1409221b1638SMasahiro Yamada     unsigned got;
1410221b1638SMasahiro Yamada     unsigned next;
1411221b1638SMasahiro Yamada 
1412221b1638SMasahiro Yamada     got = *have;
1413221b1638SMasahiro Yamada     next = 0;
1414221b1638SMasahiro Yamada     while (next < len && got < 4) {
1415221b1638SMasahiro Yamada         if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
1416221b1638SMasahiro Yamada             got++;
1417221b1638SMasahiro Yamada         else if (buf[next])
1418221b1638SMasahiro Yamada             got = 0;
1419221b1638SMasahiro Yamada         else
1420221b1638SMasahiro Yamada             got = 4 - got;
1421221b1638SMasahiro Yamada         next++;
1422221b1638SMasahiro Yamada     }
1423221b1638SMasahiro Yamada     *have = got;
1424221b1638SMasahiro Yamada     return next;
1425221b1638SMasahiro Yamada }
1426221b1638SMasahiro Yamada 
1427221b1638SMasahiro Yamada int ZEXPORT inflateSync(strm)
1428221b1638SMasahiro Yamada z_streamp strm;
1429221b1638SMasahiro Yamada {
1430221b1638SMasahiro Yamada     unsigned len;               /* number of bytes to look at or looked at */
1431*a194255dSDaniel Boulby     int flags;                  /* temporary to save header status */
1432221b1638SMasahiro Yamada     unsigned long in, out;      /* temporary to save total_in and total_out */
1433221b1638SMasahiro Yamada     unsigned char buf[4];       /* to restore bit buffer to byte string */
1434221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1435221b1638SMasahiro Yamada 
1436221b1638SMasahiro Yamada     /* check parameters */
1437221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1438221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1439221b1638SMasahiro Yamada     if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
1440221b1638SMasahiro Yamada 
1441221b1638SMasahiro Yamada     /* if first time, start search in bit buffer */
1442221b1638SMasahiro Yamada     if (state->mode != SYNC) {
1443221b1638SMasahiro Yamada         state->mode = SYNC;
1444221b1638SMasahiro Yamada         state->hold <<= state->bits & 7;
1445221b1638SMasahiro Yamada         state->bits -= state->bits & 7;
1446221b1638SMasahiro Yamada         len = 0;
1447221b1638SMasahiro Yamada         while (state->bits >= 8) {
1448221b1638SMasahiro Yamada             buf[len++] = (unsigned char)(state->hold);
1449221b1638SMasahiro Yamada             state->hold >>= 8;
1450221b1638SMasahiro Yamada             state->bits -= 8;
1451221b1638SMasahiro Yamada         }
1452221b1638SMasahiro Yamada         state->have = 0;
1453221b1638SMasahiro Yamada         syncsearch(&(state->have), buf, len);
1454221b1638SMasahiro Yamada     }
1455221b1638SMasahiro Yamada 
1456221b1638SMasahiro Yamada     /* search available input */
1457221b1638SMasahiro Yamada     len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
1458221b1638SMasahiro Yamada     strm->avail_in -= len;
1459221b1638SMasahiro Yamada     strm->next_in += len;
1460221b1638SMasahiro Yamada     strm->total_in += len;
1461221b1638SMasahiro Yamada 
1462221b1638SMasahiro Yamada     /* return no joy or set up to restart inflate() on a new block */
1463221b1638SMasahiro Yamada     if (state->have != 4) return Z_DATA_ERROR;
1464*a194255dSDaniel Boulby     if (state->flags == -1)
1465*a194255dSDaniel Boulby         state->wrap = 0;    /* if no header yet, treat as raw */
1466*a194255dSDaniel Boulby     else
1467*a194255dSDaniel Boulby         state->wrap &= ~4;  /* no point in computing a check value now */
1468*a194255dSDaniel Boulby     flags = state->flags;
1469221b1638SMasahiro Yamada     in = strm->total_in;  out = strm->total_out;
1470221b1638SMasahiro Yamada     inflateReset(strm);
1471221b1638SMasahiro Yamada     strm->total_in = in;  strm->total_out = out;
1472*a194255dSDaniel Boulby     state->flags = flags;
1473221b1638SMasahiro Yamada     state->mode = TYPE;
1474221b1638SMasahiro Yamada     return Z_OK;
1475221b1638SMasahiro Yamada }
1476221b1638SMasahiro Yamada 
1477221b1638SMasahiro Yamada /*
1478221b1638SMasahiro Yamada    Returns true if inflate is currently at the end of a block generated by
1479221b1638SMasahiro Yamada    Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
1480221b1638SMasahiro Yamada    implementation to provide an additional safety check. PPP uses
1481221b1638SMasahiro Yamada    Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
1482221b1638SMasahiro Yamada    block. When decompressing, PPP checks that at the end of input packet,
1483221b1638SMasahiro Yamada    inflate is waiting for these length bytes.
1484221b1638SMasahiro Yamada  */
1485221b1638SMasahiro Yamada int ZEXPORT inflateSyncPoint(strm)
1486221b1638SMasahiro Yamada z_streamp strm;
1487221b1638SMasahiro Yamada {
1488221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1489221b1638SMasahiro Yamada 
1490221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1491221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1492221b1638SMasahiro Yamada     return state->mode == STORED && state->bits == 0;
1493221b1638SMasahiro Yamada }
1494221b1638SMasahiro Yamada 
1495221b1638SMasahiro Yamada int ZEXPORT inflateCopy(dest, source)
1496221b1638SMasahiro Yamada z_streamp dest;
1497221b1638SMasahiro Yamada z_streamp source;
1498221b1638SMasahiro Yamada {
1499221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1500221b1638SMasahiro Yamada     struct inflate_state FAR *copy;
1501221b1638SMasahiro Yamada     unsigned char FAR *window;
1502221b1638SMasahiro Yamada     unsigned wsize;
1503221b1638SMasahiro Yamada 
1504221b1638SMasahiro Yamada     /* check input */
1505221b1638SMasahiro Yamada     if (inflateStateCheck(source) || dest == Z_NULL)
1506221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
1507221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)source->state;
1508221b1638SMasahiro Yamada 
1509221b1638SMasahiro Yamada     /* allocate space */
1510221b1638SMasahiro Yamada     copy = (struct inflate_state FAR *)
1511221b1638SMasahiro Yamada            ZALLOC(source, 1, sizeof(struct inflate_state));
1512221b1638SMasahiro Yamada     if (copy == Z_NULL) return Z_MEM_ERROR;
1513221b1638SMasahiro Yamada     window = Z_NULL;
1514221b1638SMasahiro Yamada     if (state->window != Z_NULL) {
1515221b1638SMasahiro Yamada         window = (unsigned char FAR *)
1516221b1638SMasahiro Yamada                  ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
1517221b1638SMasahiro Yamada         if (window == Z_NULL) {
1518221b1638SMasahiro Yamada             ZFREE(source, copy);
1519221b1638SMasahiro Yamada             return Z_MEM_ERROR;
1520221b1638SMasahiro Yamada         }
1521221b1638SMasahiro Yamada     }
1522221b1638SMasahiro Yamada 
1523221b1638SMasahiro Yamada     /* copy state */
1524221b1638SMasahiro Yamada     zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
1525221b1638SMasahiro Yamada     zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
1526221b1638SMasahiro Yamada     copy->strm = dest;
1527221b1638SMasahiro Yamada     if (state->lencode >= state->codes &&
1528221b1638SMasahiro Yamada         state->lencode <= state->codes + ENOUGH - 1) {
1529221b1638SMasahiro Yamada         copy->lencode = copy->codes + (state->lencode - state->codes);
1530221b1638SMasahiro Yamada         copy->distcode = copy->codes + (state->distcode - state->codes);
1531221b1638SMasahiro Yamada     }
1532221b1638SMasahiro Yamada     copy->next = copy->codes + (state->next - state->codes);
1533221b1638SMasahiro Yamada     if (window != Z_NULL) {
1534221b1638SMasahiro Yamada         wsize = 1U << state->wbits;
1535221b1638SMasahiro Yamada         zmemcpy(window, state->window, wsize);
1536221b1638SMasahiro Yamada     }
1537221b1638SMasahiro Yamada     copy->window = window;
1538221b1638SMasahiro Yamada     dest->state = (struct internal_state FAR *)copy;
1539221b1638SMasahiro Yamada     return Z_OK;
1540221b1638SMasahiro Yamada }
1541221b1638SMasahiro Yamada 
1542221b1638SMasahiro Yamada int ZEXPORT inflateUndermine(strm, subvert)
1543221b1638SMasahiro Yamada z_streamp strm;
1544221b1638SMasahiro Yamada int subvert;
1545221b1638SMasahiro Yamada {
1546221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1547221b1638SMasahiro Yamada 
1548221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1549221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1550221b1638SMasahiro Yamada #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
1551221b1638SMasahiro Yamada     state->sane = !subvert;
1552221b1638SMasahiro Yamada     return Z_OK;
1553221b1638SMasahiro Yamada #else
1554221b1638SMasahiro Yamada     (void)subvert;
1555221b1638SMasahiro Yamada     state->sane = 1;
1556221b1638SMasahiro Yamada     return Z_DATA_ERROR;
1557221b1638SMasahiro Yamada #endif
1558221b1638SMasahiro Yamada }
1559221b1638SMasahiro Yamada 
1560221b1638SMasahiro Yamada int ZEXPORT inflateValidate(strm, check)
1561221b1638SMasahiro Yamada z_streamp strm;
1562221b1638SMasahiro Yamada int check;
1563221b1638SMasahiro Yamada {
1564221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1565221b1638SMasahiro Yamada 
1566221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1567221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1568*a194255dSDaniel Boulby     if (check && state->wrap)
1569221b1638SMasahiro Yamada         state->wrap |= 4;
1570221b1638SMasahiro Yamada     else
1571221b1638SMasahiro Yamada         state->wrap &= ~4;
1572221b1638SMasahiro Yamada     return Z_OK;
1573221b1638SMasahiro Yamada }
1574221b1638SMasahiro Yamada 
1575221b1638SMasahiro Yamada long ZEXPORT inflateMark(strm)
1576221b1638SMasahiro Yamada z_streamp strm;
1577221b1638SMasahiro Yamada {
1578221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1579221b1638SMasahiro Yamada 
1580221b1638SMasahiro Yamada     if (inflateStateCheck(strm))
1581221b1638SMasahiro Yamada         return -(1L << 16);
1582221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1583221b1638SMasahiro Yamada     return (long)(((unsigned long)((long)state->back)) << 16) +
1584221b1638SMasahiro Yamada         (state->mode == COPY ? state->length :
1585221b1638SMasahiro Yamada             (state->mode == MATCH ? state->was - state->length : 0));
1586221b1638SMasahiro Yamada }
1587221b1638SMasahiro Yamada 
1588221b1638SMasahiro Yamada unsigned long ZEXPORT inflateCodesUsed(strm)
1589221b1638SMasahiro Yamada z_streamp strm;
1590221b1638SMasahiro Yamada {
1591221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1592221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return (unsigned long)-1;
1593221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1594221b1638SMasahiro Yamada     return (unsigned long)(state->next - state->codes);
1595221b1638SMasahiro Yamada }
1596