xref: /rk3399_ARM-atf/lib/zlib/inflate.c (revision 50313d071261dacc923b18c996369326101a3e8a)
1221b1638SMasahiro Yamada /* inflate.c -- zlib decompression
2a194255dSDaniel 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 
inflateStateCheck(z_streamp strm)94fd39217aSManish Pandey local int inflateStateCheck(z_streamp strm) {
95221b1638SMasahiro Yamada     struct inflate_state FAR *state;
96221b1638SMasahiro Yamada     if (strm == Z_NULL ||
97221b1638SMasahiro Yamada         strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
98221b1638SMasahiro Yamada         return 1;
99221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
100221b1638SMasahiro Yamada     if (state == Z_NULL || state->strm != strm ||
101221b1638SMasahiro Yamada         state->mode < HEAD || state->mode > SYNC)
102221b1638SMasahiro Yamada         return 1;
103221b1638SMasahiro Yamada     return 0;
104221b1638SMasahiro Yamada }
105221b1638SMasahiro Yamada 
inflateResetKeep(z_streamp strm)106fd39217aSManish Pandey int ZEXPORT inflateResetKeep(z_streamp strm) {
107221b1638SMasahiro Yamada     struct inflate_state FAR *state;
108221b1638SMasahiro Yamada 
109221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
110221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
111221b1638SMasahiro Yamada     strm->total_in = strm->total_out = state->total = 0;
112221b1638SMasahiro Yamada     strm->msg = Z_NULL;
113221b1638SMasahiro Yamada     if (state->wrap)        /* to support ill-conceived Java test suite */
114221b1638SMasahiro Yamada         strm->adler = state->wrap & 1;
115221b1638SMasahiro Yamada     state->mode = HEAD;
116221b1638SMasahiro Yamada     state->last = 0;
117221b1638SMasahiro Yamada     state->havedict = 0;
118a194255dSDaniel Boulby     state->flags = -1;
119221b1638SMasahiro Yamada     state->dmax = 32768U;
120221b1638SMasahiro Yamada     state->head = Z_NULL;
121221b1638SMasahiro Yamada     state->hold = 0;
122221b1638SMasahiro Yamada     state->bits = 0;
123221b1638SMasahiro Yamada     state->lencode = state->distcode = state->next = state->codes;
124221b1638SMasahiro Yamada     state->sane = 1;
125221b1638SMasahiro Yamada     state->back = -1;
126221b1638SMasahiro Yamada     Tracev((stderr, "inflate: reset\n"));
127221b1638SMasahiro Yamada     return Z_OK;
128221b1638SMasahiro Yamada }
129221b1638SMasahiro Yamada 
inflateReset(z_streamp strm)130fd39217aSManish Pandey int ZEXPORT inflateReset(z_streamp strm) {
131221b1638SMasahiro Yamada     struct inflate_state FAR *state;
132221b1638SMasahiro Yamada 
133221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
134221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
135221b1638SMasahiro Yamada     state->wsize = 0;
136221b1638SMasahiro Yamada     state->whave = 0;
137221b1638SMasahiro Yamada     state->wnext = 0;
138221b1638SMasahiro Yamada     return inflateResetKeep(strm);
139221b1638SMasahiro Yamada }
140221b1638SMasahiro Yamada 
inflateReset2(z_streamp strm,int windowBits)141fd39217aSManish Pandey int ZEXPORT inflateReset2(z_streamp strm, int windowBits) {
142221b1638SMasahiro Yamada     int wrap;
143221b1638SMasahiro Yamada     struct inflate_state FAR *state;
144221b1638SMasahiro Yamada 
145221b1638SMasahiro Yamada     /* get the state */
146221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
147221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
148221b1638SMasahiro Yamada 
149221b1638SMasahiro Yamada     /* extract wrap request from windowBits parameter */
150221b1638SMasahiro Yamada     if (windowBits < 0) {
151a194255dSDaniel Boulby         if (windowBits < -15)
152a194255dSDaniel Boulby             return Z_STREAM_ERROR;
153221b1638SMasahiro Yamada         wrap = 0;
154221b1638SMasahiro Yamada         windowBits = -windowBits;
155221b1638SMasahiro Yamada     }
156221b1638SMasahiro Yamada     else {
157221b1638SMasahiro Yamada         wrap = (windowBits >> 4) + 5;
158221b1638SMasahiro Yamada #ifdef GUNZIP
159221b1638SMasahiro Yamada         if (windowBits < 48)
160221b1638SMasahiro Yamada             windowBits &= 15;
161221b1638SMasahiro Yamada #endif
162221b1638SMasahiro Yamada     }
163221b1638SMasahiro Yamada 
164221b1638SMasahiro Yamada     /* set number of window bits, free window if different */
165221b1638SMasahiro Yamada     if (windowBits && (windowBits < 8 || windowBits > 15))
166221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
167221b1638SMasahiro Yamada     if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
168221b1638SMasahiro Yamada         ZFREE(strm, state->window);
169221b1638SMasahiro Yamada         state->window = Z_NULL;
170221b1638SMasahiro Yamada     }
171221b1638SMasahiro Yamada 
172221b1638SMasahiro Yamada     /* update state and reset the rest of it */
173221b1638SMasahiro Yamada     state->wrap = wrap;
174221b1638SMasahiro Yamada     state->wbits = (unsigned)windowBits;
175221b1638SMasahiro Yamada     return inflateReset(strm);
176221b1638SMasahiro Yamada }
177221b1638SMasahiro Yamada 
inflateInit2_(z_streamp strm,int windowBits,const char * version,int stream_size)178fd39217aSManish Pandey int ZEXPORT inflateInit2_(z_streamp strm, int windowBits,
179fd39217aSManish Pandey                           const char *version, int stream_size) {
180221b1638SMasahiro Yamada     int ret;
181221b1638SMasahiro Yamada     struct inflate_state FAR *state;
182221b1638SMasahiro Yamada 
183221b1638SMasahiro Yamada     if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
184221b1638SMasahiro Yamada         stream_size != (int)(sizeof(z_stream)))
185221b1638SMasahiro Yamada         return Z_VERSION_ERROR;
186221b1638SMasahiro Yamada     if (strm == Z_NULL) return Z_STREAM_ERROR;
187221b1638SMasahiro Yamada     strm->msg = Z_NULL;                 /* in case we return an error */
188221b1638SMasahiro Yamada     if (strm->zalloc == (alloc_func)0) {
189221b1638SMasahiro Yamada #ifdef Z_SOLO
190221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
191221b1638SMasahiro Yamada #else
192221b1638SMasahiro Yamada         strm->zalloc = zcalloc;
193221b1638SMasahiro Yamada         strm->opaque = (voidpf)0;
194221b1638SMasahiro Yamada #endif
195221b1638SMasahiro Yamada     }
196221b1638SMasahiro Yamada     if (strm->zfree == (free_func)0)
197221b1638SMasahiro Yamada #ifdef Z_SOLO
198221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
199221b1638SMasahiro Yamada #else
200221b1638SMasahiro Yamada         strm->zfree = zcfree;
201221b1638SMasahiro Yamada #endif
202221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)
203221b1638SMasahiro Yamada             ZALLOC(strm, 1, sizeof(struct inflate_state));
204221b1638SMasahiro Yamada     if (state == Z_NULL) return Z_MEM_ERROR;
205221b1638SMasahiro Yamada     Tracev((stderr, "inflate: allocated\n"));
206221b1638SMasahiro Yamada     strm->state = (struct internal_state FAR *)state;
207221b1638SMasahiro Yamada     state->strm = strm;
208221b1638SMasahiro Yamada     state->window = Z_NULL;
209221b1638SMasahiro Yamada     state->mode = HEAD;     /* to pass state test in inflateReset2() */
210221b1638SMasahiro Yamada     ret = inflateReset2(strm, windowBits);
211221b1638SMasahiro Yamada     if (ret != Z_OK) {
212221b1638SMasahiro Yamada         ZFREE(strm, state);
213221b1638SMasahiro Yamada         strm->state = Z_NULL;
214221b1638SMasahiro Yamada     }
215221b1638SMasahiro Yamada     return ret;
216221b1638SMasahiro Yamada }
217221b1638SMasahiro Yamada 
inflateInit_(z_streamp strm,const char * version,int stream_size)218fd39217aSManish Pandey int ZEXPORT inflateInit_(z_streamp strm, const char *version,
219fd39217aSManish Pandey                          int stream_size) {
220221b1638SMasahiro Yamada     return inflateInit2_(strm, DEF_WBITS, version, stream_size);
221221b1638SMasahiro Yamada }
222221b1638SMasahiro Yamada 
inflatePrime(z_streamp strm,int bits,int value)223fd39217aSManish Pandey int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) {
224221b1638SMasahiro Yamada     struct inflate_state FAR *state;
225221b1638SMasahiro Yamada 
226221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
227fd39217aSManish Pandey     if (bits == 0)
228fd39217aSManish Pandey         return Z_OK;
229221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
230221b1638SMasahiro Yamada     if (bits < 0) {
231221b1638SMasahiro Yamada         state->hold = 0;
232221b1638SMasahiro Yamada         state->bits = 0;
233221b1638SMasahiro Yamada         return Z_OK;
234221b1638SMasahiro Yamada     }
235221b1638SMasahiro Yamada     if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;
236221b1638SMasahiro Yamada     value &= (1L << bits) - 1;
237221b1638SMasahiro Yamada     state->hold += (unsigned)value << state->bits;
238221b1638SMasahiro Yamada     state->bits += (uInt)bits;
239221b1638SMasahiro Yamada     return Z_OK;
240221b1638SMasahiro Yamada }
241221b1638SMasahiro Yamada 
242221b1638SMasahiro Yamada /*
243221b1638SMasahiro Yamada    Return state with length and distance decoding tables and index sizes set to
244221b1638SMasahiro Yamada    fixed code decoding.  Normally this returns fixed tables from inffixed.h.
245221b1638SMasahiro Yamada    If BUILDFIXED is defined, then instead this routine builds the tables the
246221b1638SMasahiro Yamada    first time it's called, and returns those tables the first time and
247221b1638SMasahiro Yamada    thereafter.  This reduces the size of the code by about 2K bytes, in
248221b1638SMasahiro Yamada    exchange for a little execution time.  However, BUILDFIXED should not be
249221b1638SMasahiro Yamada    used for threaded applications, since the rewriting of the tables and virgin
250221b1638SMasahiro Yamada    may not be thread-safe.
251221b1638SMasahiro Yamada  */
fixedtables(struct inflate_state FAR * state)252fd39217aSManish Pandey local void fixedtables(struct inflate_state FAR *state) {
253221b1638SMasahiro Yamada #ifdef BUILDFIXED
254221b1638SMasahiro Yamada     static int virgin = 1;
255221b1638SMasahiro Yamada     static code *lenfix, *distfix;
256221b1638SMasahiro Yamada     static code fixed[544];
257221b1638SMasahiro Yamada 
258221b1638SMasahiro Yamada     /* build fixed huffman tables if first call (may not be thread safe) */
259221b1638SMasahiro Yamada     if (virgin) {
260221b1638SMasahiro Yamada         unsigned sym, bits;
261221b1638SMasahiro Yamada         static code *next;
262221b1638SMasahiro Yamada 
263221b1638SMasahiro Yamada         /* literal/length table */
264221b1638SMasahiro Yamada         sym = 0;
265221b1638SMasahiro Yamada         while (sym < 144) state->lens[sym++] = 8;
266221b1638SMasahiro Yamada         while (sym < 256) state->lens[sym++] = 9;
267221b1638SMasahiro Yamada         while (sym < 280) state->lens[sym++] = 7;
268221b1638SMasahiro Yamada         while (sym < 288) state->lens[sym++] = 8;
269221b1638SMasahiro Yamada         next = fixed;
270221b1638SMasahiro Yamada         lenfix = next;
271221b1638SMasahiro Yamada         bits = 9;
272221b1638SMasahiro Yamada         inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
273221b1638SMasahiro Yamada 
274221b1638SMasahiro Yamada         /* distance table */
275221b1638SMasahiro Yamada         sym = 0;
276221b1638SMasahiro Yamada         while (sym < 32) state->lens[sym++] = 5;
277221b1638SMasahiro Yamada         distfix = next;
278221b1638SMasahiro Yamada         bits = 5;
279221b1638SMasahiro Yamada         inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
280221b1638SMasahiro Yamada 
281221b1638SMasahiro Yamada         /* do this just once */
282221b1638SMasahiro Yamada         virgin = 0;
283221b1638SMasahiro Yamada     }
284221b1638SMasahiro Yamada #else /* !BUILDFIXED */
285221b1638SMasahiro Yamada #   include "inffixed.h"
286221b1638SMasahiro Yamada #endif /* BUILDFIXED */
287221b1638SMasahiro Yamada     state->lencode = lenfix;
288221b1638SMasahiro Yamada     state->lenbits = 9;
289221b1638SMasahiro Yamada     state->distcode = distfix;
290221b1638SMasahiro Yamada     state->distbits = 5;
291221b1638SMasahiro Yamada }
292221b1638SMasahiro Yamada 
293221b1638SMasahiro Yamada #ifdef MAKEFIXED
294221b1638SMasahiro Yamada #include <stdio.h>
295221b1638SMasahiro Yamada 
296221b1638SMasahiro Yamada /*
297221b1638SMasahiro Yamada    Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
298221b1638SMasahiro Yamada    defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
299221b1638SMasahiro Yamada    those tables to stdout, which would be piped to inffixed.h.  A small program
300221b1638SMasahiro Yamada    can simply call makefixed to do this:
301221b1638SMasahiro Yamada 
302221b1638SMasahiro Yamada     void makefixed(void);
303221b1638SMasahiro Yamada 
304221b1638SMasahiro Yamada     int main(void)
305221b1638SMasahiro Yamada     {
306221b1638SMasahiro Yamada         makefixed();
307221b1638SMasahiro Yamada         return 0;
308221b1638SMasahiro Yamada     }
309221b1638SMasahiro Yamada 
310221b1638SMasahiro Yamada    Then that can be linked with zlib built with MAKEFIXED defined and run:
311221b1638SMasahiro Yamada 
312221b1638SMasahiro Yamada     a.out > inffixed.h
313221b1638SMasahiro Yamada  */
makefixed(void)3142535e204SElyes Haouas void makefixed(void)
315221b1638SMasahiro Yamada {
316221b1638SMasahiro Yamada     unsigned low, size;
317221b1638SMasahiro Yamada     struct inflate_state state;
318221b1638SMasahiro Yamada 
319221b1638SMasahiro Yamada     fixedtables(&state);
320221b1638SMasahiro Yamada     puts("    /* inffixed.h -- table for decoding fixed codes");
321221b1638SMasahiro Yamada     puts("     * Generated automatically by makefixed().");
322221b1638SMasahiro Yamada     puts("     */");
323221b1638SMasahiro Yamada     puts("");
324221b1638SMasahiro Yamada     puts("    /* WARNING: this file should *not* be used by applications.");
325221b1638SMasahiro Yamada     puts("       It is part of the implementation of this library and is");
326221b1638SMasahiro Yamada     puts("       subject to change. Applications should only use zlib.h.");
327221b1638SMasahiro Yamada     puts("     */");
328221b1638SMasahiro Yamada     puts("");
329221b1638SMasahiro Yamada     size = 1U << 9;
330221b1638SMasahiro Yamada     printf("    static const code lenfix[%u] = {", size);
331221b1638SMasahiro Yamada     low = 0;
332221b1638SMasahiro Yamada     for (;;) {
333221b1638SMasahiro Yamada         if ((low % 7) == 0) printf("\n        ");
334221b1638SMasahiro Yamada         printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
335221b1638SMasahiro Yamada                state.lencode[low].bits, state.lencode[low].val);
336221b1638SMasahiro Yamada         if (++low == size) break;
337221b1638SMasahiro Yamada         putchar(',');
338221b1638SMasahiro Yamada     }
339221b1638SMasahiro Yamada     puts("\n    };");
340221b1638SMasahiro Yamada     size = 1U << 5;
341221b1638SMasahiro Yamada     printf("\n    static const code distfix[%u] = {", size);
342221b1638SMasahiro Yamada     low = 0;
343221b1638SMasahiro Yamada     for (;;) {
344221b1638SMasahiro Yamada         if ((low % 6) == 0) printf("\n        ");
345221b1638SMasahiro Yamada         printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
346221b1638SMasahiro Yamada                state.distcode[low].val);
347221b1638SMasahiro Yamada         if (++low == size) break;
348221b1638SMasahiro Yamada         putchar(',');
349221b1638SMasahiro Yamada     }
350221b1638SMasahiro Yamada     puts("\n    };");
351221b1638SMasahiro Yamada }
352221b1638SMasahiro Yamada #endif /* MAKEFIXED */
353221b1638SMasahiro Yamada 
354221b1638SMasahiro Yamada /*
355221b1638SMasahiro Yamada    Update the window with the last wsize (normally 32K) bytes written before
356221b1638SMasahiro Yamada    returning.  If window does not exist yet, create it.  This is only called
357221b1638SMasahiro Yamada    when a window is already in use, or when output has been written during this
358221b1638SMasahiro Yamada    inflate call, but the end of the deflate stream has not been reached yet.
359221b1638SMasahiro Yamada    It is also called to create a window for dictionary data when a dictionary
360221b1638SMasahiro Yamada    is loaded.
361221b1638SMasahiro Yamada 
362221b1638SMasahiro Yamada    Providing output buffers larger than 32K to inflate() should provide a speed
363221b1638SMasahiro Yamada    advantage, since only the last 32K of output is copied to the sliding window
364221b1638SMasahiro Yamada    upon return from inflate(), and since all distances after the first 32K of
365221b1638SMasahiro Yamada    output will fall in the output data, making match copies simpler and faster.
366221b1638SMasahiro Yamada    The advantage may be dependent on the size of the processor's data caches.
367221b1638SMasahiro Yamada  */
updatewindow(z_streamp strm,const Bytef * end,unsigned copy)368fd39217aSManish Pandey local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) {
369221b1638SMasahiro Yamada     struct inflate_state FAR *state;
370221b1638SMasahiro Yamada     unsigned dist;
371221b1638SMasahiro Yamada 
372221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
373221b1638SMasahiro Yamada 
374221b1638SMasahiro Yamada     /* if it hasn't been done already, allocate space for the window */
375221b1638SMasahiro Yamada     if (state->window == Z_NULL) {
376221b1638SMasahiro Yamada         state->window = (unsigned char FAR *)
377221b1638SMasahiro Yamada                         ZALLOC(strm, 1U << state->wbits,
378221b1638SMasahiro Yamada                                sizeof(unsigned char));
379221b1638SMasahiro Yamada         if (state->window == Z_NULL) return 1;
380221b1638SMasahiro Yamada     }
381221b1638SMasahiro Yamada 
382221b1638SMasahiro Yamada     /* if window not in use yet, initialize */
383221b1638SMasahiro Yamada     if (state->wsize == 0) {
384221b1638SMasahiro Yamada         state->wsize = 1U << state->wbits;
385221b1638SMasahiro Yamada         state->wnext = 0;
386221b1638SMasahiro Yamada         state->whave = 0;
387221b1638SMasahiro Yamada     }
388221b1638SMasahiro Yamada 
389221b1638SMasahiro Yamada     /* copy state->wsize or less output bytes into the circular window */
390221b1638SMasahiro Yamada     if (copy >= state->wsize) {
391221b1638SMasahiro Yamada         zmemcpy(state->window, end - state->wsize, state->wsize);
392221b1638SMasahiro Yamada         state->wnext = 0;
393221b1638SMasahiro Yamada         state->whave = state->wsize;
394221b1638SMasahiro Yamada     }
395221b1638SMasahiro Yamada     else {
396221b1638SMasahiro Yamada         dist = state->wsize - state->wnext;
397221b1638SMasahiro Yamada         if (dist > copy) dist = copy;
398221b1638SMasahiro Yamada         zmemcpy(state->window + state->wnext, end - copy, dist);
399221b1638SMasahiro Yamada         copy -= dist;
400221b1638SMasahiro Yamada         if (copy) {
401221b1638SMasahiro Yamada             zmemcpy(state->window, end - copy, copy);
402221b1638SMasahiro Yamada             state->wnext = copy;
403221b1638SMasahiro Yamada             state->whave = state->wsize;
404221b1638SMasahiro Yamada         }
405221b1638SMasahiro Yamada         else {
406221b1638SMasahiro Yamada             state->wnext += dist;
407221b1638SMasahiro Yamada             if (state->wnext == state->wsize) state->wnext = 0;
408221b1638SMasahiro Yamada             if (state->whave < state->wsize) state->whave += dist;
409221b1638SMasahiro Yamada         }
410221b1638SMasahiro Yamada     }
411221b1638SMasahiro Yamada     return 0;
412221b1638SMasahiro Yamada }
413221b1638SMasahiro Yamada 
414221b1638SMasahiro Yamada /* Macros for inflate(): */
415221b1638SMasahiro Yamada 
416221b1638SMasahiro Yamada /* check function to use adler32() for zlib or crc32() for gzip */
417221b1638SMasahiro Yamada #ifdef GUNZIP
418a194255dSDaniel Boulby #  define UPDATE_CHECK(check, buf, len) \
419221b1638SMasahiro Yamada     (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
420221b1638SMasahiro Yamada #else
421a194255dSDaniel Boulby #  define UPDATE_CHECK(check, buf, len) adler32(check, buf, len)
422221b1638SMasahiro Yamada #endif
423221b1638SMasahiro Yamada 
424221b1638SMasahiro Yamada /* check macros for header crc */
425221b1638SMasahiro Yamada #ifdef GUNZIP
426221b1638SMasahiro Yamada #  define CRC2(check, word) \
427221b1638SMasahiro Yamada     do { \
428221b1638SMasahiro Yamada         hbuf[0] = (unsigned char)(word); \
429221b1638SMasahiro Yamada         hbuf[1] = (unsigned char)((word) >> 8); \
430221b1638SMasahiro Yamada         check = crc32(check, hbuf, 2); \
431221b1638SMasahiro Yamada     } while (0)
432221b1638SMasahiro Yamada 
433221b1638SMasahiro Yamada #  define CRC4(check, word) \
434221b1638SMasahiro Yamada     do { \
435221b1638SMasahiro Yamada         hbuf[0] = (unsigned char)(word); \
436221b1638SMasahiro Yamada         hbuf[1] = (unsigned char)((word) >> 8); \
437221b1638SMasahiro Yamada         hbuf[2] = (unsigned char)((word) >> 16); \
438221b1638SMasahiro Yamada         hbuf[3] = (unsigned char)((word) >> 24); \
439221b1638SMasahiro Yamada         check = crc32(check, hbuf, 4); \
440221b1638SMasahiro Yamada     } while (0)
441221b1638SMasahiro Yamada #endif
442221b1638SMasahiro Yamada 
443221b1638SMasahiro Yamada /* Load registers with state in inflate() for speed */
444221b1638SMasahiro Yamada #define LOAD() \
445221b1638SMasahiro Yamada     do { \
446221b1638SMasahiro Yamada         put = strm->next_out; \
447221b1638SMasahiro Yamada         left = strm->avail_out; \
448221b1638SMasahiro Yamada         next = strm->next_in; \
449221b1638SMasahiro Yamada         have = strm->avail_in; \
450221b1638SMasahiro Yamada         hold = state->hold; \
451221b1638SMasahiro Yamada         bits = state->bits; \
452221b1638SMasahiro Yamada     } while (0)
453221b1638SMasahiro Yamada 
454221b1638SMasahiro Yamada /* Restore state from registers in inflate() */
455221b1638SMasahiro Yamada #define RESTORE() \
456221b1638SMasahiro Yamada     do { \
457221b1638SMasahiro Yamada         strm->next_out = put; \
458221b1638SMasahiro Yamada         strm->avail_out = left; \
459221b1638SMasahiro Yamada         strm->next_in = next; \
460221b1638SMasahiro Yamada         strm->avail_in = have; \
461221b1638SMasahiro Yamada         state->hold = hold; \
462221b1638SMasahiro Yamada         state->bits = bits; \
463221b1638SMasahiro Yamada     } while (0)
464221b1638SMasahiro Yamada 
465221b1638SMasahiro Yamada /* Clear the input bit accumulator */
466221b1638SMasahiro Yamada #define INITBITS() \
467221b1638SMasahiro Yamada     do { \
468221b1638SMasahiro Yamada         hold = 0; \
469221b1638SMasahiro Yamada         bits = 0; \
470221b1638SMasahiro Yamada     } while (0)
471221b1638SMasahiro Yamada 
472221b1638SMasahiro Yamada /* Get a byte of input into the bit accumulator, or return from inflate()
473221b1638SMasahiro Yamada    if there is no input available. */
474221b1638SMasahiro Yamada #define PULLBYTE() \
475221b1638SMasahiro Yamada     do { \
476221b1638SMasahiro Yamada         if (have == 0) goto inf_leave; \
477221b1638SMasahiro Yamada         have--; \
478221b1638SMasahiro Yamada         hold += (unsigned long)(*next++) << bits; \
479221b1638SMasahiro Yamada         bits += 8; \
480221b1638SMasahiro Yamada     } while (0)
481221b1638SMasahiro Yamada 
482221b1638SMasahiro Yamada /* Assure that there are at least n bits in the bit accumulator.  If there is
483221b1638SMasahiro Yamada    not enough available input to do that, then return from inflate(). */
484221b1638SMasahiro Yamada #define NEEDBITS(n) \
485221b1638SMasahiro Yamada     do { \
486221b1638SMasahiro Yamada         while (bits < (unsigned)(n)) \
487221b1638SMasahiro Yamada             PULLBYTE(); \
488221b1638SMasahiro Yamada     } while (0)
489221b1638SMasahiro Yamada 
490221b1638SMasahiro Yamada /* Return the low n bits of the bit accumulator (n < 16) */
491221b1638SMasahiro Yamada #define BITS(n) \
492221b1638SMasahiro Yamada     ((unsigned)hold & ((1U << (n)) - 1))
493221b1638SMasahiro Yamada 
494221b1638SMasahiro Yamada /* Remove n bits from the bit accumulator */
495221b1638SMasahiro Yamada #define DROPBITS(n) \
496221b1638SMasahiro Yamada     do { \
497221b1638SMasahiro Yamada         hold >>= (n); \
498221b1638SMasahiro Yamada         bits -= (unsigned)(n); \
499221b1638SMasahiro Yamada     } while (0)
500221b1638SMasahiro Yamada 
501221b1638SMasahiro Yamada /* Remove zero to seven bits as needed to go to a byte boundary */
502221b1638SMasahiro Yamada #define BYTEBITS() \
503221b1638SMasahiro Yamada     do { \
504221b1638SMasahiro Yamada         hold >>= bits & 7; \
505221b1638SMasahiro Yamada         bits -= bits & 7; \
506221b1638SMasahiro Yamada     } while (0)
507221b1638SMasahiro Yamada 
508221b1638SMasahiro Yamada /*
509221b1638SMasahiro Yamada    inflate() uses a state machine to process as much input data and generate as
510221b1638SMasahiro Yamada    much output data as possible before returning.  The state machine is
511221b1638SMasahiro Yamada    structured roughly as follows:
512221b1638SMasahiro Yamada 
513221b1638SMasahiro Yamada     for (;;) switch (state) {
514221b1638SMasahiro Yamada     ...
515221b1638SMasahiro Yamada     case STATEn:
516221b1638SMasahiro Yamada         if (not enough input data or output space to make progress)
517221b1638SMasahiro Yamada             return;
518221b1638SMasahiro Yamada         ... make progress ...
519221b1638SMasahiro Yamada         state = STATEm;
520221b1638SMasahiro Yamada         break;
521221b1638SMasahiro Yamada     ...
522221b1638SMasahiro Yamada     }
523221b1638SMasahiro Yamada 
524221b1638SMasahiro Yamada    so when inflate() is called again, the same case is attempted again, and
525221b1638SMasahiro Yamada    if the appropriate resources are provided, the machine proceeds to the
526221b1638SMasahiro Yamada    next state.  The NEEDBITS() macro is usually the way the state evaluates
527221b1638SMasahiro Yamada    whether it can proceed or should return.  NEEDBITS() does the return if
528221b1638SMasahiro Yamada    the requested bits are not available.  The typical use of the BITS macros
529221b1638SMasahiro Yamada    is:
530221b1638SMasahiro Yamada 
531221b1638SMasahiro Yamada         NEEDBITS(n);
532221b1638SMasahiro Yamada         ... do something with BITS(n) ...
533221b1638SMasahiro Yamada         DROPBITS(n);
534221b1638SMasahiro Yamada 
535221b1638SMasahiro Yamada    where NEEDBITS(n) either returns from inflate() if there isn't enough
536221b1638SMasahiro Yamada    input left to load n bits into the accumulator, or it continues.  BITS(n)
537221b1638SMasahiro Yamada    gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
538221b1638SMasahiro Yamada    the low n bits off the accumulator.  INITBITS() clears the accumulator
539221b1638SMasahiro Yamada    and sets the number of available bits to zero.  BYTEBITS() discards just
540221b1638SMasahiro Yamada    enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
541221b1638SMasahiro Yamada    and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
542221b1638SMasahiro Yamada 
543221b1638SMasahiro Yamada    NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
544221b1638SMasahiro Yamada    if there is no input available.  The decoding of variable length codes uses
545221b1638SMasahiro Yamada    PULLBYTE() directly in order to pull just enough bytes to decode the next
546221b1638SMasahiro Yamada    code, and no more.
547221b1638SMasahiro Yamada 
548221b1638SMasahiro Yamada    Some states loop until they get enough input, making sure that enough
549221b1638SMasahiro Yamada    state information is maintained to continue the loop where it left off
550221b1638SMasahiro Yamada    if NEEDBITS() returns in the loop.  For example, want, need, and keep
551221b1638SMasahiro Yamada    would all have to actually be part of the saved state in case NEEDBITS()
552221b1638SMasahiro Yamada    returns:
553221b1638SMasahiro Yamada 
554221b1638SMasahiro Yamada     case STATEw:
555221b1638SMasahiro Yamada         while (want < need) {
556221b1638SMasahiro Yamada             NEEDBITS(n);
557221b1638SMasahiro Yamada             keep[want++] = BITS(n);
558221b1638SMasahiro Yamada             DROPBITS(n);
559221b1638SMasahiro Yamada         }
560221b1638SMasahiro Yamada         state = STATEx;
561221b1638SMasahiro Yamada     case STATEx:
562221b1638SMasahiro Yamada 
563221b1638SMasahiro Yamada    As shown above, if the next state is also the next case, then the break
564221b1638SMasahiro Yamada    is omitted.
565221b1638SMasahiro Yamada 
566221b1638SMasahiro Yamada    A state may also return if there is not enough output space available to
567221b1638SMasahiro Yamada    complete that state.  Those states are copying stored data, writing a
568221b1638SMasahiro Yamada    literal byte, and copying a matching string.
569221b1638SMasahiro Yamada 
570221b1638SMasahiro Yamada    When returning, a "goto inf_leave" is used to update the total counters,
571221b1638SMasahiro Yamada    update the check value, and determine whether any progress has been made
572221b1638SMasahiro Yamada    during that inflate() call in order to return the proper return code.
573221b1638SMasahiro Yamada    Progress is defined as a change in either strm->avail_in or strm->avail_out.
574221b1638SMasahiro Yamada    When there is a window, goto inf_leave will update the window with the last
575221b1638SMasahiro Yamada    output written.  If a goto inf_leave occurs in the middle of decompression
576221b1638SMasahiro Yamada    and there is no window currently, goto inf_leave will create one and copy
577221b1638SMasahiro Yamada    output to the window for the next call of inflate().
578221b1638SMasahiro Yamada 
579221b1638SMasahiro Yamada    In this implementation, the flush parameter of inflate() only affects the
580221b1638SMasahiro Yamada    return code (per zlib.h).  inflate() always writes as much as possible to
581221b1638SMasahiro Yamada    strm->next_out, given the space available and the provided input--the effect
582221b1638SMasahiro Yamada    documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
583221b1638SMasahiro Yamada    the allocation of and copying into a sliding window until necessary, which
584221b1638SMasahiro Yamada    provides the effect documented in zlib.h for Z_FINISH when the entire input
585221b1638SMasahiro Yamada    stream available.  So the only thing the flush parameter actually does is:
586221b1638SMasahiro Yamada    when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
587221b1638SMasahiro Yamada    will return Z_BUF_ERROR if it has not reached the end of the stream.
588221b1638SMasahiro Yamada  */
589221b1638SMasahiro Yamada 
inflate(z_streamp strm,int flush)590fd39217aSManish Pandey int ZEXPORT inflate(z_streamp strm, int flush) {
591221b1638SMasahiro Yamada     struct inflate_state FAR *state;
592221b1638SMasahiro Yamada     z_const unsigned char FAR *next;    /* next input */
593221b1638SMasahiro Yamada     unsigned char FAR *put;     /* next output */
594221b1638SMasahiro Yamada     unsigned have, left;        /* available input and output */
595221b1638SMasahiro Yamada     unsigned long hold;         /* bit buffer */
596221b1638SMasahiro Yamada     unsigned bits;              /* bits in bit buffer */
597221b1638SMasahiro Yamada     unsigned in, out;           /* save starting available input and output */
598221b1638SMasahiro Yamada     unsigned copy;              /* number of stored or match bytes to copy */
599221b1638SMasahiro Yamada     unsigned char FAR *from;    /* where to copy match bytes from */
600221b1638SMasahiro Yamada     code here;                  /* current decoding table entry */
601221b1638SMasahiro Yamada     code last;                  /* parent table entry */
602221b1638SMasahiro Yamada     unsigned len;               /* length to copy for repeats, bits to drop */
603221b1638SMasahiro Yamada     int ret;                    /* return code */
604221b1638SMasahiro Yamada #ifdef GUNZIP
605221b1638SMasahiro Yamada     unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
606221b1638SMasahiro Yamada #endif
607221b1638SMasahiro Yamada     static const unsigned short order[19] = /* permutation of code lengths */
608221b1638SMasahiro Yamada         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
609221b1638SMasahiro Yamada 
610221b1638SMasahiro Yamada     if (inflateStateCheck(strm) || strm->next_out == Z_NULL ||
611221b1638SMasahiro Yamada         (strm->next_in == Z_NULL && strm->avail_in != 0))
612221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
613221b1638SMasahiro Yamada 
614221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
615221b1638SMasahiro Yamada     if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
616221b1638SMasahiro Yamada     LOAD();
617221b1638SMasahiro Yamada     in = have;
618221b1638SMasahiro Yamada     out = left;
619221b1638SMasahiro Yamada     ret = Z_OK;
620221b1638SMasahiro Yamada     for (;;)
621221b1638SMasahiro Yamada         switch (state->mode) {
622221b1638SMasahiro Yamada         case HEAD:
623221b1638SMasahiro Yamada             if (state->wrap == 0) {
624221b1638SMasahiro Yamada                 state->mode = TYPEDO;
625221b1638SMasahiro Yamada                 break;
626221b1638SMasahiro Yamada             }
627221b1638SMasahiro Yamada             NEEDBITS(16);
628221b1638SMasahiro Yamada #ifdef GUNZIP
629221b1638SMasahiro Yamada             if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
630221b1638SMasahiro Yamada                 if (state->wbits == 0)
631221b1638SMasahiro Yamada                     state->wbits = 15;
632221b1638SMasahiro Yamada                 state->check = crc32(0L, Z_NULL, 0);
633221b1638SMasahiro Yamada                 CRC2(state->check, hold);
634221b1638SMasahiro Yamada                 INITBITS();
635221b1638SMasahiro Yamada                 state->mode = FLAGS;
636221b1638SMasahiro Yamada                 break;
637221b1638SMasahiro Yamada             }
638221b1638SMasahiro Yamada             if (state->head != Z_NULL)
639221b1638SMasahiro Yamada                 state->head->done = -1;
640221b1638SMasahiro Yamada             if (!(state->wrap & 1) ||   /* check if zlib header allowed */
641221b1638SMasahiro Yamada #else
642221b1638SMasahiro Yamada             if (
643221b1638SMasahiro Yamada #endif
644221b1638SMasahiro Yamada                 ((BITS(8) << 8) + (hold >> 8)) % 31) {
645*a8c877cbSChris Kay                 strm->msg = (z_const char *)"incorrect header check";
646221b1638SMasahiro Yamada                 state->mode = BAD;
647221b1638SMasahiro Yamada                 break;
648221b1638SMasahiro Yamada             }
649221b1638SMasahiro Yamada             if (BITS(4) != Z_DEFLATED) {
650*a8c877cbSChris Kay                 strm->msg = (z_const char *)"unknown compression method";
651221b1638SMasahiro Yamada                 state->mode = BAD;
652221b1638SMasahiro Yamada                 break;
653221b1638SMasahiro Yamada             }
654221b1638SMasahiro Yamada             DROPBITS(4);
655221b1638SMasahiro Yamada             len = BITS(4) + 8;
656221b1638SMasahiro Yamada             if (state->wbits == 0)
657221b1638SMasahiro Yamada                 state->wbits = len;
658221b1638SMasahiro Yamada             if (len > 15 || len > state->wbits) {
659*a8c877cbSChris Kay                 strm->msg = (z_const char *)"invalid window size";
660221b1638SMasahiro Yamada                 state->mode = BAD;
661221b1638SMasahiro Yamada                 break;
662221b1638SMasahiro Yamada             }
663221b1638SMasahiro Yamada             state->dmax = 1U << len;
664a194255dSDaniel Boulby             state->flags = 0;               /* indicate zlib header */
665221b1638SMasahiro Yamada             Tracev((stderr, "inflate:   zlib header ok\n"));
666221b1638SMasahiro Yamada             strm->adler = state->check = adler32(0L, Z_NULL, 0);
667221b1638SMasahiro Yamada             state->mode = hold & 0x200 ? DICTID : TYPE;
668221b1638SMasahiro Yamada             INITBITS();
669221b1638SMasahiro Yamada             break;
670221b1638SMasahiro Yamada #ifdef GUNZIP
671221b1638SMasahiro Yamada         case FLAGS:
672221b1638SMasahiro Yamada             NEEDBITS(16);
673221b1638SMasahiro Yamada             state->flags = (int)(hold);
674221b1638SMasahiro Yamada             if ((state->flags & 0xff) != Z_DEFLATED) {
675*a8c877cbSChris Kay                 strm->msg = (z_const char *)"unknown compression method";
676221b1638SMasahiro Yamada                 state->mode = BAD;
677221b1638SMasahiro Yamada                 break;
678221b1638SMasahiro Yamada             }
679221b1638SMasahiro Yamada             if (state->flags & 0xe000) {
680*a8c877cbSChris Kay                 strm->msg = (z_const char *)"unknown header flags set";
681221b1638SMasahiro Yamada                 state->mode = BAD;
682221b1638SMasahiro Yamada                 break;
683221b1638SMasahiro Yamada             }
684221b1638SMasahiro Yamada             if (state->head != Z_NULL)
685221b1638SMasahiro Yamada                 state->head->text = (int)((hold >> 8) & 1);
686221b1638SMasahiro Yamada             if ((state->flags & 0x0200) && (state->wrap & 4))
687221b1638SMasahiro Yamada                 CRC2(state->check, hold);
688221b1638SMasahiro Yamada             INITBITS();
689221b1638SMasahiro Yamada             state->mode = TIME;
690a194255dSDaniel Boulby                 /* fallthrough */
691221b1638SMasahiro Yamada         case TIME:
692221b1638SMasahiro Yamada             NEEDBITS(32);
693221b1638SMasahiro Yamada             if (state->head != Z_NULL)
694221b1638SMasahiro Yamada                 state->head->time = hold;
695221b1638SMasahiro Yamada             if ((state->flags & 0x0200) && (state->wrap & 4))
696221b1638SMasahiro Yamada                 CRC4(state->check, hold);
697221b1638SMasahiro Yamada             INITBITS();
698221b1638SMasahiro Yamada             state->mode = OS;
699a194255dSDaniel Boulby                 /* fallthrough */
700221b1638SMasahiro Yamada         case OS:
701221b1638SMasahiro Yamada             NEEDBITS(16);
702221b1638SMasahiro Yamada             if (state->head != Z_NULL) {
703221b1638SMasahiro Yamada                 state->head->xflags = (int)(hold & 0xff);
704221b1638SMasahiro Yamada                 state->head->os = (int)(hold >> 8);
705221b1638SMasahiro Yamada             }
706221b1638SMasahiro Yamada             if ((state->flags & 0x0200) && (state->wrap & 4))
707221b1638SMasahiro Yamada                 CRC2(state->check, hold);
708221b1638SMasahiro Yamada             INITBITS();
709221b1638SMasahiro Yamada             state->mode = EXLEN;
710a194255dSDaniel Boulby                 /* fallthrough */
711221b1638SMasahiro Yamada         case EXLEN:
712221b1638SMasahiro Yamada             if (state->flags & 0x0400) {
713221b1638SMasahiro Yamada                 NEEDBITS(16);
714221b1638SMasahiro Yamada                 state->length = (unsigned)(hold);
715221b1638SMasahiro Yamada                 if (state->head != Z_NULL)
716221b1638SMasahiro Yamada                     state->head->extra_len = (unsigned)hold;
717221b1638SMasahiro Yamada                 if ((state->flags & 0x0200) && (state->wrap & 4))
718221b1638SMasahiro Yamada                     CRC2(state->check, hold);
719221b1638SMasahiro Yamada                 INITBITS();
720221b1638SMasahiro Yamada             }
721221b1638SMasahiro Yamada             else if (state->head != Z_NULL)
722221b1638SMasahiro Yamada                 state->head->extra = Z_NULL;
723221b1638SMasahiro Yamada             state->mode = EXTRA;
724a194255dSDaniel Boulby                 /* fallthrough */
725221b1638SMasahiro Yamada         case EXTRA:
726221b1638SMasahiro Yamada             if (state->flags & 0x0400) {
727221b1638SMasahiro Yamada                 copy = state->length;
728221b1638SMasahiro Yamada                 if (copy > have) copy = have;
729221b1638SMasahiro Yamada                 if (copy) {
730221b1638SMasahiro Yamada                     if (state->head != Z_NULL &&
731a194255dSDaniel Boulby                         state->head->extra != Z_NULL &&
732a194255dSDaniel Boulby                         (len = state->head->extra_len - state->length) <
733a194255dSDaniel Boulby                             state->head->extra_max) {
734221b1638SMasahiro Yamada                         zmemcpy(state->head->extra + len, next,
735221b1638SMasahiro Yamada                                 len + copy > state->head->extra_max ?
736221b1638SMasahiro Yamada                                 state->head->extra_max - len : copy);
737221b1638SMasahiro Yamada                     }
738221b1638SMasahiro Yamada                     if ((state->flags & 0x0200) && (state->wrap & 4))
739221b1638SMasahiro Yamada                         state->check = crc32(state->check, next, copy);
740221b1638SMasahiro Yamada                     have -= copy;
741221b1638SMasahiro Yamada                     next += copy;
742221b1638SMasahiro Yamada                     state->length -= copy;
743221b1638SMasahiro Yamada                 }
744221b1638SMasahiro Yamada                 if (state->length) goto inf_leave;
745221b1638SMasahiro Yamada             }
746221b1638SMasahiro Yamada             state->length = 0;
747221b1638SMasahiro Yamada             state->mode = NAME;
748a194255dSDaniel Boulby                 /* fallthrough */
749221b1638SMasahiro Yamada         case NAME:
750221b1638SMasahiro Yamada             if (state->flags & 0x0800) {
751221b1638SMasahiro Yamada                 if (have == 0) goto inf_leave;
752221b1638SMasahiro Yamada                 copy = 0;
753221b1638SMasahiro Yamada                 do {
754221b1638SMasahiro Yamada                     len = (unsigned)(next[copy++]);
755221b1638SMasahiro Yamada                     if (state->head != Z_NULL &&
756221b1638SMasahiro Yamada                             state->head->name != Z_NULL &&
757221b1638SMasahiro Yamada                             state->length < state->head->name_max)
758221b1638SMasahiro Yamada                         state->head->name[state->length++] = (Bytef)len;
759221b1638SMasahiro Yamada                 } while (len && copy < have);
760221b1638SMasahiro Yamada                 if ((state->flags & 0x0200) && (state->wrap & 4))
761221b1638SMasahiro Yamada                     state->check = crc32(state->check, next, copy);
762221b1638SMasahiro Yamada                 have -= copy;
763221b1638SMasahiro Yamada                 next += copy;
764221b1638SMasahiro Yamada                 if (len) goto inf_leave;
765221b1638SMasahiro Yamada             }
766221b1638SMasahiro Yamada             else if (state->head != Z_NULL)
767221b1638SMasahiro Yamada                 state->head->name = Z_NULL;
768221b1638SMasahiro Yamada             state->length = 0;
769221b1638SMasahiro Yamada             state->mode = COMMENT;
770a194255dSDaniel Boulby                 /* fallthrough */
771221b1638SMasahiro Yamada         case COMMENT:
772221b1638SMasahiro Yamada             if (state->flags & 0x1000) {
773221b1638SMasahiro Yamada                 if (have == 0) goto inf_leave;
774221b1638SMasahiro Yamada                 copy = 0;
775221b1638SMasahiro Yamada                 do {
776221b1638SMasahiro Yamada                     len = (unsigned)(next[copy++]);
777221b1638SMasahiro Yamada                     if (state->head != Z_NULL &&
778221b1638SMasahiro Yamada                             state->head->comment != Z_NULL &&
779221b1638SMasahiro Yamada                             state->length < state->head->comm_max)
780221b1638SMasahiro Yamada                         state->head->comment[state->length++] = (Bytef)len;
781221b1638SMasahiro Yamada                 } while (len && copy < have);
782221b1638SMasahiro Yamada                 if ((state->flags & 0x0200) && (state->wrap & 4))
783221b1638SMasahiro Yamada                     state->check = crc32(state->check, next, copy);
784221b1638SMasahiro Yamada                 have -= copy;
785221b1638SMasahiro Yamada                 next += copy;
786221b1638SMasahiro Yamada                 if (len) goto inf_leave;
787221b1638SMasahiro Yamada             }
788221b1638SMasahiro Yamada             else if (state->head != Z_NULL)
789221b1638SMasahiro Yamada                 state->head->comment = Z_NULL;
790221b1638SMasahiro Yamada             state->mode = HCRC;
791a194255dSDaniel Boulby                 /* fallthrough */
792221b1638SMasahiro Yamada         case HCRC:
793221b1638SMasahiro Yamada             if (state->flags & 0x0200) {
794221b1638SMasahiro Yamada                 NEEDBITS(16);
795221b1638SMasahiro Yamada                 if ((state->wrap & 4) && hold != (state->check & 0xffff)) {
796*a8c877cbSChris Kay                     strm->msg = (z_const char *)"header crc mismatch";
797221b1638SMasahiro Yamada                     state->mode = BAD;
798221b1638SMasahiro Yamada                     break;
799221b1638SMasahiro Yamada                 }
800221b1638SMasahiro Yamada                 INITBITS();
801221b1638SMasahiro Yamada             }
802221b1638SMasahiro Yamada             if (state->head != Z_NULL) {
803221b1638SMasahiro Yamada                 state->head->hcrc = (int)((state->flags >> 9) & 1);
804221b1638SMasahiro Yamada                 state->head->done = 1;
805221b1638SMasahiro Yamada             }
806221b1638SMasahiro Yamada             strm->adler = state->check = crc32(0L, Z_NULL, 0);
807221b1638SMasahiro Yamada             state->mode = TYPE;
808221b1638SMasahiro Yamada             break;
809221b1638SMasahiro Yamada #endif
810221b1638SMasahiro Yamada         case DICTID:
811221b1638SMasahiro Yamada             NEEDBITS(32);
812221b1638SMasahiro Yamada             strm->adler = state->check = ZSWAP32(hold);
813221b1638SMasahiro Yamada             INITBITS();
814221b1638SMasahiro Yamada             state->mode = DICT;
815a194255dSDaniel Boulby                 /* fallthrough */
816221b1638SMasahiro Yamada         case DICT:
817221b1638SMasahiro Yamada             if (state->havedict == 0) {
818221b1638SMasahiro Yamada                 RESTORE();
819221b1638SMasahiro Yamada                 return Z_NEED_DICT;
820221b1638SMasahiro Yamada             }
821221b1638SMasahiro Yamada             strm->adler = state->check = adler32(0L, Z_NULL, 0);
822221b1638SMasahiro Yamada             state->mode = TYPE;
823a194255dSDaniel Boulby                 /* fallthrough */
824221b1638SMasahiro Yamada         case TYPE:
825221b1638SMasahiro Yamada             if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
826a194255dSDaniel Boulby                 /* fallthrough */
827221b1638SMasahiro Yamada         case TYPEDO:
828221b1638SMasahiro Yamada             if (state->last) {
829221b1638SMasahiro Yamada                 BYTEBITS();
830221b1638SMasahiro Yamada                 state->mode = CHECK;
831221b1638SMasahiro Yamada                 break;
832221b1638SMasahiro Yamada             }
833221b1638SMasahiro Yamada             NEEDBITS(3);
834221b1638SMasahiro Yamada             state->last = BITS(1);
835221b1638SMasahiro Yamada             DROPBITS(1);
836221b1638SMasahiro Yamada             switch (BITS(2)) {
837221b1638SMasahiro Yamada             case 0:                             /* stored block */
838221b1638SMasahiro Yamada                 Tracev((stderr, "inflate:     stored block%s\n",
839221b1638SMasahiro Yamada                         state->last ? " (last)" : ""));
840221b1638SMasahiro Yamada                 state->mode = STORED;
841221b1638SMasahiro Yamada                 break;
842221b1638SMasahiro Yamada             case 1:                             /* fixed block */
843221b1638SMasahiro Yamada                 fixedtables(state);
844221b1638SMasahiro Yamada                 Tracev((stderr, "inflate:     fixed codes block%s\n",
845221b1638SMasahiro Yamada                         state->last ? " (last)" : ""));
846221b1638SMasahiro Yamada                 state->mode = LEN_;             /* decode codes */
847221b1638SMasahiro Yamada                 if (flush == Z_TREES) {
848221b1638SMasahiro Yamada                     DROPBITS(2);
849221b1638SMasahiro Yamada                     goto inf_leave;
850221b1638SMasahiro Yamada                 }
851221b1638SMasahiro Yamada                 break;
852221b1638SMasahiro Yamada             case 2:                             /* dynamic block */
853221b1638SMasahiro Yamada                 Tracev((stderr, "inflate:     dynamic codes block%s\n",
854221b1638SMasahiro Yamada                         state->last ? " (last)" : ""));
855221b1638SMasahiro Yamada                 state->mode = TABLE;
856221b1638SMasahiro Yamada                 break;
857221b1638SMasahiro Yamada             case 3:
858*a8c877cbSChris Kay                 strm->msg = (z_const char *)"invalid block type";
859221b1638SMasahiro Yamada                 state->mode = BAD;
860221b1638SMasahiro Yamada             }
861221b1638SMasahiro Yamada             DROPBITS(2);
862221b1638SMasahiro Yamada             break;
863221b1638SMasahiro Yamada         case STORED:
864221b1638SMasahiro Yamada             BYTEBITS();                         /* go to byte boundary */
865221b1638SMasahiro Yamada             NEEDBITS(32);
866221b1638SMasahiro Yamada             if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
867*a8c877cbSChris Kay                 strm->msg = (z_const char *)"invalid stored block lengths";
868221b1638SMasahiro Yamada                 state->mode = BAD;
869221b1638SMasahiro Yamada                 break;
870221b1638SMasahiro Yamada             }
871221b1638SMasahiro Yamada             state->length = (unsigned)hold & 0xffff;
872221b1638SMasahiro Yamada             Tracev((stderr, "inflate:       stored length %u\n",
873221b1638SMasahiro Yamada                     state->length));
874221b1638SMasahiro Yamada             INITBITS();
875221b1638SMasahiro Yamada             state->mode = COPY_;
876221b1638SMasahiro Yamada             if (flush == Z_TREES) goto inf_leave;
877a194255dSDaniel Boulby                 /* fallthrough */
878221b1638SMasahiro Yamada         case COPY_:
879221b1638SMasahiro Yamada             state->mode = COPY;
880a194255dSDaniel Boulby                 /* fallthrough */
881221b1638SMasahiro Yamada         case COPY:
882221b1638SMasahiro Yamada             copy = state->length;
883221b1638SMasahiro Yamada             if (copy) {
884221b1638SMasahiro Yamada                 if (copy > have) copy = have;
885221b1638SMasahiro Yamada                 if (copy > left) copy = left;
886221b1638SMasahiro Yamada                 if (copy == 0) goto inf_leave;
887221b1638SMasahiro Yamada                 zmemcpy(put, next, copy);
888221b1638SMasahiro Yamada                 have -= copy;
889221b1638SMasahiro Yamada                 next += copy;
890221b1638SMasahiro Yamada                 left -= copy;
891221b1638SMasahiro Yamada                 put += copy;
892221b1638SMasahiro Yamada                 state->length -= copy;
893221b1638SMasahiro Yamada                 break;
894221b1638SMasahiro Yamada             }
895221b1638SMasahiro Yamada             Tracev((stderr, "inflate:       stored end\n"));
896221b1638SMasahiro Yamada             state->mode = TYPE;
897221b1638SMasahiro Yamada             break;
898221b1638SMasahiro Yamada         case TABLE:
899221b1638SMasahiro Yamada             NEEDBITS(14);
900221b1638SMasahiro Yamada             state->nlen = BITS(5) + 257;
901221b1638SMasahiro Yamada             DROPBITS(5);
902221b1638SMasahiro Yamada             state->ndist = BITS(5) + 1;
903221b1638SMasahiro Yamada             DROPBITS(5);
904221b1638SMasahiro Yamada             state->ncode = BITS(4) + 4;
905221b1638SMasahiro Yamada             DROPBITS(4);
906221b1638SMasahiro Yamada #ifndef PKZIP_BUG_WORKAROUND
907221b1638SMasahiro Yamada             if (state->nlen > 286 || state->ndist > 30) {
908*a8c877cbSChris Kay                 strm->msg = (z_const char *)"too many length or distance symbols";
909221b1638SMasahiro Yamada                 state->mode = BAD;
910221b1638SMasahiro Yamada                 break;
911221b1638SMasahiro Yamada             }
912221b1638SMasahiro Yamada #endif
913221b1638SMasahiro Yamada             Tracev((stderr, "inflate:       table sizes ok\n"));
914221b1638SMasahiro Yamada             state->have = 0;
915221b1638SMasahiro Yamada             state->mode = LENLENS;
916a194255dSDaniel Boulby                 /* fallthrough */
917221b1638SMasahiro Yamada         case LENLENS:
918221b1638SMasahiro Yamada             while (state->have < state->ncode) {
919221b1638SMasahiro Yamada                 NEEDBITS(3);
920221b1638SMasahiro Yamada                 state->lens[order[state->have++]] = (unsigned short)BITS(3);
921221b1638SMasahiro Yamada                 DROPBITS(3);
922221b1638SMasahiro Yamada             }
923221b1638SMasahiro Yamada             while (state->have < 19)
924221b1638SMasahiro Yamada                 state->lens[order[state->have++]] = 0;
925221b1638SMasahiro Yamada             state->next = state->codes;
926*a8c877cbSChris Kay             state->lencode = state->distcode = (const code FAR *)(state->next);
927221b1638SMasahiro Yamada             state->lenbits = 7;
928221b1638SMasahiro Yamada             ret = inflate_table(CODES, state->lens, 19, &(state->next),
929221b1638SMasahiro Yamada                                 &(state->lenbits), state->work);
930221b1638SMasahiro Yamada             if (ret) {
931*a8c877cbSChris Kay                 strm->msg = (z_const char *)"invalid code lengths set";
932221b1638SMasahiro Yamada                 state->mode = BAD;
933221b1638SMasahiro Yamada                 break;
934221b1638SMasahiro Yamada             }
935221b1638SMasahiro Yamada             Tracev((stderr, "inflate:       code lengths ok\n"));
936221b1638SMasahiro Yamada             state->have = 0;
937221b1638SMasahiro Yamada             state->mode = CODELENS;
938a194255dSDaniel Boulby                 /* fallthrough */
939221b1638SMasahiro Yamada         case CODELENS:
940221b1638SMasahiro Yamada             while (state->have < state->nlen + state->ndist) {
941221b1638SMasahiro Yamada                 for (;;) {
942221b1638SMasahiro Yamada                     here = state->lencode[BITS(state->lenbits)];
943221b1638SMasahiro Yamada                     if ((unsigned)(here.bits) <= bits) break;
944221b1638SMasahiro Yamada                     PULLBYTE();
945221b1638SMasahiro Yamada                 }
946221b1638SMasahiro Yamada                 if (here.val < 16) {
947221b1638SMasahiro Yamada                     DROPBITS(here.bits);
948221b1638SMasahiro Yamada                     state->lens[state->have++] = here.val;
949221b1638SMasahiro Yamada                 }
950221b1638SMasahiro Yamada                 else {
951221b1638SMasahiro Yamada                     if (here.val == 16) {
952221b1638SMasahiro Yamada                         NEEDBITS(here.bits + 2);
953221b1638SMasahiro Yamada                         DROPBITS(here.bits);
954221b1638SMasahiro Yamada                         if (state->have == 0) {
955*a8c877cbSChris Kay                             strm->msg = (z_const char *)"invalid bit length repeat";
956221b1638SMasahiro Yamada                             state->mode = BAD;
957221b1638SMasahiro Yamada                             break;
958221b1638SMasahiro Yamada                         }
959221b1638SMasahiro Yamada                         len = state->lens[state->have - 1];
960221b1638SMasahiro Yamada                         copy = 3 + BITS(2);
961221b1638SMasahiro Yamada                         DROPBITS(2);
962221b1638SMasahiro Yamada                     }
963221b1638SMasahiro Yamada                     else if (here.val == 17) {
964221b1638SMasahiro Yamada                         NEEDBITS(here.bits + 3);
965221b1638SMasahiro Yamada                         DROPBITS(here.bits);
966221b1638SMasahiro Yamada                         len = 0;
967221b1638SMasahiro Yamada                         copy = 3 + BITS(3);
968221b1638SMasahiro Yamada                         DROPBITS(3);
969221b1638SMasahiro Yamada                     }
970221b1638SMasahiro Yamada                     else {
971221b1638SMasahiro Yamada                         NEEDBITS(here.bits + 7);
972221b1638SMasahiro Yamada                         DROPBITS(here.bits);
973221b1638SMasahiro Yamada                         len = 0;
974221b1638SMasahiro Yamada                         copy = 11 + BITS(7);
975221b1638SMasahiro Yamada                         DROPBITS(7);
976221b1638SMasahiro Yamada                     }
977221b1638SMasahiro Yamada                     if (state->have + copy > state->nlen + state->ndist) {
978*a8c877cbSChris Kay                         strm->msg = (z_const char *)"invalid bit length repeat";
979221b1638SMasahiro Yamada                         state->mode = BAD;
980221b1638SMasahiro Yamada                         break;
981221b1638SMasahiro Yamada                     }
982221b1638SMasahiro Yamada                     while (copy--)
983221b1638SMasahiro Yamada                         state->lens[state->have++] = (unsigned short)len;
984221b1638SMasahiro Yamada                 }
985221b1638SMasahiro Yamada             }
986221b1638SMasahiro Yamada 
987221b1638SMasahiro Yamada             /* handle error breaks in while */
988221b1638SMasahiro Yamada             if (state->mode == BAD) break;
989221b1638SMasahiro Yamada 
990221b1638SMasahiro Yamada             /* check for end-of-block code (better have one) */
991221b1638SMasahiro Yamada             if (state->lens[256] == 0) {
992*a8c877cbSChris Kay                 strm->msg = (z_const char *)"invalid code -- missing end-of-block";
993221b1638SMasahiro Yamada                 state->mode = BAD;
994221b1638SMasahiro Yamada                 break;
995221b1638SMasahiro Yamada             }
996221b1638SMasahiro Yamada 
997221b1638SMasahiro Yamada             /* build code tables -- note: do not change the lenbits or distbits
998221b1638SMasahiro Yamada                values here (9 and 6) without reading the comments in inftrees.h
999221b1638SMasahiro Yamada                concerning the ENOUGH constants, which depend on those values */
1000221b1638SMasahiro Yamada             state->next = state->codes;
1001221b1638SMasahiro Yamada             state->lencode = (const code FAR *)(state->next);
1002221b1638SMasahiro Yamada             state->lenbits = 9;
1003221b1638SMasahiro Yamada             ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
1004221b1638SMasahiro Yamada                                 &(state->lenbits), state->work);
1005221b1638SMasahiro Yamada             if (ret) {
1006*a8c877cbSChris Kay                 strm->msg = (z_const char *)"invalid literal/lengths set";
1007221b1638SMasahiro Yamada                 state->mode = BAD;
1008221b1638SMasahiro Yamada                 break;
1009221b1638SMasahiro Yamada             }
1010221b1638SMasahiro Yamada             state->distcode = (const code FAR *)(state->next);
1011221b1638SMasahiro Yamada             state->distbits = 6;
1012221b1638SMasahiro Yamada             ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
1013221b1638SMasahiro Yamada                             &(state->next), &(state->distbits), state->work);
1014221b1638SMasahiro Yamada             if (ret) {
1015*a8c877cbSChris Kay                 strm->msg = (z_const char *)"invalid distances set";
1016221b1638SMasahiro Yamada                 state->mode = BAD;
1017221b1638SMasahiro Yamada                 break;
1018221b1638SMasahiro Yamada             }
1019221b1638SMasahiro Yamada             Tracev((stderr, "inflate:       codes ok\n"));
1020221b1638SMasahiro Yamada             state->mode = LEN_;
1021221b1638SMasahiro Yamada             if (flush == Z_TREES) goto inf_leave;
1022a194255dSDaniel Boulby                 /* fallthrough */
1023221b1638SMasahiro Yamada         case LEN_:
1024221b1638SMasahiro Yamada             state->mode = LEN;
1025a194255dSDaniel Boulby                 /* fallthrough */
1026221b1638SMasahiro Yamada         case LEN:
1027221b1638SMasahiro Yamada             if (have >= 6 && left >= 258) {
1028221b1638SMasahiro Yamada                 RESTORE();
1029221b1638SMasahiro Yamada                 inflate_fast(strm, out);
1030221b1638SMasahiro Yamada                 LOAD();
1031221b1638SMasahiro Yamada                 if (state->mode == TYPE)
1032221b1638SMasahiro Yamada                     state->back = -1;
1033221b1638SMasahiro Yamada                 break;
1034221b1638SMasahiro Yamada             }
1035221b1638SMasahiro Yamada             state->back = 0;
1036221b1638SMasahiro Yamada             for (;;) {
1037221b1638SMasahiro Yamada                 here = state->lencode[BITS(state->lenbits)];
1038221b1638SMasahiro Yamada                 if ((unsigned)(here.bits) <= bits) break;
1039221b1638SMasahiro Yamada                 PULLBYTE();
1040221b1638SMasahiro Yamada             }
1041221b1638SMasahiro Yamada             if (here.op && (here.op & 0xf0) == 0) {
1042221b1638SMasahiro Yamada                 last = here;
1043221b1638SMasahiro Yamada                 for (;;) {
1044221b1638SMasahiro Yamada                     here = state->lencode[last.val +
1045221b1638SMasahiro Yamada                             (BITS(last.bits + last.op) >> last.bits)];
1046221b1638SMasahiro Yamada                     if ((unsigned)(last.bits + here.bits) <= bits) break;
1047221b1638SMasahiro Yamada                     PULLBYTE();
1048221b1638SMasahiro Yamada                 }
1049221b1638SMasahiro Yamada                 DROPBITS(last.bits);
1050221b1638SMasahiro Yamada                 state->back += last.bits;
1051221b1638SMasahiro Yamada             }
1052221b1638SMasahiro Yamada             DROPBITS(here.bits);
1053221b1638SMasahiro Yamada             state->back += here.bits;
1054221b1638SMasahiro Yamada             state->length = (unsigned)here.val;
1055221b1638SMasahiro Yamada             if ((int)(here.op) == 0) {
1056221b1638SMasahiro Yamada                 Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
1057221b1638SMasahiro Yamada                         "inflate:         literal '%c'\n" :
1058221b1638SMasahiro Yamada                         "inflate:         literal 0x%02x\n", here.val));
1059221b1638SMasahiro Yamada                 state->mode = LIT;
1060221b1638SMasahiro Yamada                 break;
1061221b1638SMasahiro Yamada             }
1062221b1638SMasahiro Yamada             if (here.op & 32) {
1063221b1638SMasahiro Yamada                 Tracevv((stderr, "inflate:         end of block\n"));
1064221b1638SMasahiro Yamada                 state->back = -1;
1065221b1638SMasahiro Yamada                 state->mode = TYPE;
1066221b1638SMasahiro Yamada                 break;
1067221b1638SMasahiro Yamada             }
1068221b1638SMasahiro Yamada             if (here.op & 64) {
1069*a8c877cbSChris Kay                 strm->msg = (z_const char *)"invalid literal/length code";
1070221b1638SMasahiro Yamada                 state->mode = BAD;
1071221b1638SMasahiro Yamada                 break;
1072221b1638SMasahiro Yamada             }
1073221b1638SMasahiro Yamada             state->extra = (unsigned)(here.op) & 15;
1074221b1638SMasahiro Yamada             state->mode = LENEXT;
1075a194255dSDaniel Boulby                 /* fallthrough */
1076221b1638SMasahiro Yamada         case LENEXT:
1077221b1638SMasahiro Yamada             if (state->extra) {
1078221b1638SMasahiro Yamada                 NEEDBITS(state->extra);
1079221b1638SMasahiro Yamada                 state->length += BITS(state->extra);
1080221b1638SMasahiro Yamada                 DROPBITS(state->extra);
1081221b1638SMasahiro Yamada                 state->back += state->extra;
1082221b1638SMasahiro Yamada             }
1083221b1638SMasahiro Yamada             Tracevv((stderr, "inflate:         length %u\n", state->length));
1084221b1638SMasahiro Yamada             state->was = state->length;
1085221b1638SMasahiro Yamada             state->mode = DIST;
1086a194255dSDaniel Boulby                 /* fallthrough */
1087221b1638SMasahiro Yamada         case DIST:
1088221b1638SMasahiro Yamada             for (;;) {
1089221b1638SMasahiro Yamada                 here = state->distcode[BITS(state->distbits)];
1090221b1638SMasahiro Yamada                 if ((unsigned)(here.bits) <= bits) break;
1091221b1638SMasahiro Yamada                 PULLBYTE();
1092221b1638SMasahiro Yamada             }
1093221b1638SMasahiro Yamada             if ((here.op & 0xf0) == 0) {
1094221b1638SMasahiro Yamada                 last = here;
1095221b1638SMasahiro Yamada                 for (;;) {
1096221b1638SMasahiro Yamada                     here = state->distcode[last.val +
1097221b1638SMasahiro Yamada                             (BITS(last.bits + last.op) >> last.bits)];
1098221b1638SMasahiro Yamada                     if ((unsigned)(last.bits + here.bits) <= bits) break;
1099221b1638SMasahiro Yamada                     PULLBYTE();
1100221b1638SMasahiro Yamada                 }
1101221b1638SMasahiro Yamada                 DROPBITS(last.bits);
1102221b1638SMasahiro Yamada                 state->back += last.bits;
1103221b1638SMasahiro Yamada             }
1104221b1638SMasahiro Yamada             DROPBITS(here.bits);
1105221b1638SMasahiro Yamada             state->back += here.bits;
1106221b1638SMasahiro Yamada             if (here.op & 64) {
1107*a8c877cbSChris Kay                 strm->msg = (z_const char *)"invalid distance code";
1108221b1638SMasahiro Yamada                 state->mode = BAD;
1109221b1638SMasahiro Yamada                 break;
1110221b1638SMasahiro Yamada             }
1111221b1638SMasahiro Yamada             state->offset = (unsigned)here.val;
1112221b1638SMasahiro Yamada             state->extra = (unsigned)(here.op) & 15;
1113221b1638SMasahiro Yamada             state->mode = DISTEXT;
1114a194255dSDaniel Boulby                 /* fallthrough */
1115221b1638SMasahiro Yamada         case DISTEXT:
1116221b1638SMasahiro Yamada             if (state->extra) {
1117221b1638SMasahiro Yamada                 NEEDBITS(state->extra);
1118221b1638SMasahiro Yamada                 state->offset += BITS(state->extra);
1119221b1638SMasahiro Yamada                 DROPBITS(state->extra);
1120221b1638SMasahiro Yamada                 state->back += state->extra;
1121221b1638SMasahiro Yamada             }
1122221b1638SMasahiro Yamada #ifdef INFLATE_STRICT
1123221b1638SMasahiro Yamada             if (state->offset > state->dmax) {
1124*a8c877cbSChris Kay                 strm->msg = (z_const char *)"invalid distance too far back";
1125221b1638SMasahiro Yamada                 state->mode = BAD;
1126221b1638SMasahiro Yamada                 break;
1127221b1638SMasahiro Yamada             }
1128221b1638SMasahiro Yamada #endif
1129221b1638SMasahiro Yamada             Tracevv((stderr, "inflate:         distance %u\n", state->offset));
1130221b1638SMasahiro Yamada             state->mode = MATCH;
1131a194255dSDaniel Boulby                 /* fallthrough */
1132221b1638SMasahiro Yamada         case MATCH:
1133221b1638SMasahiro Yamada             if (left == 0) goto inf_leave;
1134221b1638SMasahiro Yamada             copy = out - left;
1135221b1638SMasahiro Yamada             if (state->offset > copy) {         /* copy from window */
1136221b1638SMasahiro Yamada                 copy = state->offset - copy;
1137221b1638SMasahiro Yamada                 if (copy > state->whave) {
1138221b1638SMasahiro Yamada                     if (state->sane) {
1139*a8c877cbSChris Kay                         strm->msg = (z_const char *)"invalid distance too far back";
1140221b1638SMasahiro Yamada                         state->mode = BAD;
1141221b1638SMasahiro Yamada                         break;
1142221b1638SMasahiro Yamada                     }
1143221b1638SMasahiro Yamada #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
1144221b1638SMasahiro Yamada                     Trace((stderr, "inflate.c too far\n"));
1145221b1638SMasahiro Yamada                     copy -= state->whave;
1146221b1638SMasahiro Yamada                     if (copy > state->length) copy = state->length;
1147221b1638SMasahiro Yamada                     if (copy > left) copy = left;
1148221b1638SMasahiro Yamada                     left -= copy;
1149221b1638SMasahiro Yamada                     state->length -= copy;
1150221b1638SMasahiro Yamada                     do {
1151221b1638SMasahiro Yamada                         *put++ = 0;
1152221b1638SMasahiro Yamada                     } while (--copy);
1153221b1638SMasahiro Yamada                     if (state->length == 0) state->mode = LEN;
1154221b1638SMasahiro Yamada                     break;
1155221b1638SMasahiro Yamada #endif
1156221b1638SMasahiro Yamada                 }
1157221b1638SMasahiro Yamada                 if (copy > state->wnext) {
1158221b1638SMasahiro Yamada                     copy -= state->wnext;
1159221b1638SMasahiro Yamada                     from = state->window + (state->wsize - copy);
1160221b1638SMasahiro Yamada                 }
1161221b1638SMasahiro Yamada                 else
1162221b1638SMasahiro Yamada                     from = state->window + (state->wnext - copy);
1163221b1638SMasahiro Yamada                 if (copy > state->length) copy = state->length;
1164221b1638SMasahiro Yamada             }
1165221b1638SMasahiro Yamada             else {                              /* copy from output */
1166221b1638SMasahiro Yamada                 from = put - state->offset;
1167221b1638SMasahiro Yamada                 copy = state->length;
1168221b1638SMasahiro Yamada             }
1169221b1638SMasahiro Yamada             if (copy > left) copy = left;
1170221b1638SMasahiro Yamada             left -= copy;
1171221b1638SMasahiro Yamada             state->length -= copy;
1172221b1638SMasahiro Yamada             do {
1173221b1638SMasahiro Yamada                 *put++ = *from++;
1174221b1638SMasahiro Yamada             } while (--copy);
1175221b1638SMasahiro Yamada             if (state->length == 0) state->mode = LEN;
1176221b1638SMasahiro Yamada             break;
1177221b1638SMasahiro Yamada         case LIT:
1178221b1638SMasahiro Yamada             if (left == 0) goto inf_leave;
1179221b1638SMasahiro Yamada             *put++ = (unsigned char)(state->length);
1180221b1638SMasahiro Yamada             left--;
1181221b1638SMasahiro Yamada             state->mode = LEN;
1182221b1638SMasahiro Yamada             break;
1183221b1638SMasahiro Yamada         case CHECK:
1184221b1638SMasahiro Yamada             if (state->wrap) {
1185221b1638SMasahiro Yamada                 NEEDBITS(32);
1186221b1638SMasahiro Yamada                 out -= left;
1187221b1638SMasahiro Yamada                 strm->total_out += out;
1188221b1638SMasahiro Yamada                 state->total += out;
1189221b1638SMasahiro Yamada                 if ((state->wrap & 4) && out)
1190221b1638SMasahiro Yamada                     strm->adler = state->check =
1191a194255dSDaniel Boulby                         UPDATE_CHECK(state->check, put - out, out);
1192221b1638SMasahiro Yamada                 out = left;
1193221b1638SMasahiro Yamada                 if ((state->wrap & 4) && (
1194221b1638SMasahiro Yamada #ifdef GUNZIP
1195221b1638SMasahiro Yamada                      state->flags ? hold :
1196221b1638SMasahiro Yamada #endif
1197221b1638SMasahiro Yamada                      ZSWAP32(hold)) != state->check) {
1198*a8c877cbSChris Kay                     strm->msg = (z_const char *)"incorrect data check";
1199221b1638SMasahiro Yamada                     state->mode = BAD;
1200221b1638SMasahiro Yamada                     break;
1201221b1638SMasahiro Yamada                 }
1202221b1638SMasahiro Yamada                 INITBITS();
1203221b1638SMasahiro Yamada                 Tracev((stderr, "inflate:   check matches trailer\n"));
1204221b1638SMasahiro Yamada             }
1205221b1638SMasahiro Yamada #ifdef GUNZIP
1206221b1638SMasahiro Yamada             state->mode = LENGTH;
1207a194255dSDaniel Boulby                 /* fallthrough */
1208221b1638SMasahiro Yamada         case LENGTH:
1209221b1638SMasahiro Yamada             if (state->wrap && state->flags) {
1210221b1638SMasahiro Yamada                 NEEDBITS(32);
1211a194255dSDaniel Boulby                 if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) {
1212*a8c877cbSChris Kay                     strm->msg = (z_const char *)"incorrect length check";
1213221b1638SMasahiro Yamada                     state->mode = BAD;
1214221b1638SMasahiro Yamada                     break;
1215221b1638SMasahiro Yamada                 }
1216221b1638SMasahiro Yamada                 INITBITS();
1217221b1638SMasahiro Yamada                 Tracev((stderr, "inflate:   length matches trailer\n"));
1218221b1638SMasahiro Yamada             }
1219221b1638SMasahiro Yamada #endif
1220221b1638SMasahiro Yamada             state->mode = DONE;
1221a194255dSDaniel Boulby                 /* fallthrough */
1222221b1638SMasahiro Yamada         case DONE:
1223221b1638SMasahiro Yamada             ret = Z_STREAM_END;
1224221b1638SMasahiro Yamada             goto inf_leave;
1225221b1638SMasahiro Yamada         case BAD:
1226221b1638SMasahiro Yamada             ret = Z_DATA_ERROR;
1227221b1638SMasahiro Yamada             goto inf_leave;
1228221b1638SMasahiro Yamada         case MEM:
1229221b1638SMasahiro Yamada             return Z_MEM_ERROR;
1230221b1638SMasahiro Yamada         case SYNC:
1231a194255dSDaniel Boulby                 /* fallthrough */
1232221b1638SMasahiro Yamada         default:
1233221b1638SMasahiro Yamada             return Z_STREAM_ERROR;
1234221b1638SMasahiro Yamada         }
1235221b1638SMasahiro Yamada 
1236221b1638SMasahiro Yamada     /*
1237221b1638SMasahiro Yamada        Return from inflate(), updating the total counts and the check value.
1238221b1638SMasahiro Yamada        If there was no progress during the inflate() call, return a buffer
1239221b1638SMasahiro Yamada        error.  Call updatewindow() to create and/or update the window state.
1240221b1638SMasahiro Yamada        Note: a memory error from inflate() is non-recoverable.
1241221b1638SMasahiro Yamada      */
1242221b1638SMasahiro Yamada   inf_leave:
1243221b1638SMasahiro Yamada     RESTORE();
1244221b1638SMasahiro Yamada     if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
1245221b1638SMasahiro Yamada             (state->mode < CHECK || flush != Z_FINISH)))
1246221b1638SMasahiro Yamada         if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
1247221b1638SMasahiro Yamada             state->mode = MEM;
1248221b1638SMasahiro Yamada             return Z_MEM_ERROR;
1249221b1638SMasahiro Yamada         }
1250221b1638SMasahiro Yamada     in -= strm->avail_in;
1251221b1638SMasahiro Yamada     out -= strm->avail_out;
1252221b1638SMasahiro Yamada     strm->total_in += in;
1253221b1638SMasahiro Yamada     strm->total_out += out;
1254221b1638SMasahiro Yamada     state->total += out;
1255221b1638SMasahiro Yamada     if ((state->wrap & 4) && out)
1256221b1638SMasahiro Yamada         strm->adler = state->check =
1257a194255dSDaniel Boulby             UPDATE_CHECK(state->check, strm->next_out - out, out);
1258221b1638SMasahiro Yamada     strm->data_type = (int)state->bits + (state->last ? 64 : 0) +
1259221b1638SMasahiro Yamada                       (state->mode == TYPE ? 128 : 0) +
1260221b1638SMasahiro Yamada                       (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
1261221b1638SMasahiro Yamada     if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
1262221b1638SMasahiro Yamada         ret = Z_BUF_ERROR;
1263221b1638SMasahiro Yamada     return ret;
1264221b1638SMasahiro Yamada }
1265221b1638SMasahiro Yamada 
inflateEnd(z_streamp strm)1266fd39217aSManish Pandey int ZEXPORT inflateEnd(z_streamp strm) {
1267221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1268221b1638SMasahiro Yamada     if (inflateStateCheck(strm))
1269221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
1270221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1271221b1638SMasahiro Yamada     if (state->window != Z_NULL) ZFREE(strm, state->window);
1272221b1638SMasahiro Yamada     ZFREE(strm, strm->state);
1273221b1638SMasahiro Yamada     strm->state = Z_NULL;
1274221b1638SMasahiro Yamada     Tracev((stderr, "inflate: end\n"));
1275221b1638SMasahiro Yamada     return Z_OK;
1276221b1638SMasahiro Yamada }
1277221b1638SMasahiro Yamada 
inflateGetDictionary(z_streamp strm,Bytef * dictionary,uInt * dictLength)1278fd39217aSManish Pandey int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary,
1279fd39217aSManish Pandey                                  uInt *dictLength) {
1280221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1281221b1638SMasahiro Yamada 
1282221b1638SMasahiro Yamada     /* check state */
1283221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1284221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1285221b1638SMasahiro Yamada 
1286221b1638SMasahiro Yamada     /* copy dictionary */
1287221b1638SMasahiro Yamada     if (state->whave && dictionary != Z_NULL) {
1288221b1638SMasahiro Yamada         zmemcpy(dictionary, state->window + state->wnext,
1289221b1638SMasahiro Yamada                 state->whave - state->wnext);
1290221b1638SMasahiro Yamada         zmemcpy(dictionary + state->whave - state->wnext,
1291221b1638SMasahiro Yamada                 state->window, state->wnext);
1292221b1638SMasahiro Yamada     }
1293221b1638SMasahiro Yamada     if (dictLength != Z_NULL)
1294221b1638SMasahiro Yamada         *dictLength = state->whave;
1295221b1638SMasahiro Yamada     return Z_OK;
1296221b1638SMasahiro Yamada }
1297221b1638SMasahiro Yamada 
inflateSetDictionary(z_streamp strm,const Bytef * dictionary,uInt dictLength)1298fd39217aSManish Pandey int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary,
1299fd39217aSManish Pandey                                  uInt dictLength) {
1300221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1301221b1638SMasahiro Yamada     unsigned long dictid;
1302221b1638SMasahiro Yamada     int ret;
1303221b1638SMasahiro Yamada 
1304221b1638SMasahiro Yamada     /* check state */
1305221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1306221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1307221b1638SMasahiro Yamada     if (state->wrap != 0 && state->mode != DICT)
1308221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
1309221b1638SMasahiro Yamada 
1310221b1638SMasahiro Yamada     /* check for correct dictionary identifier */
1311221b1638SMasahiro Yamada     if (state->mode == DICT) {
1312221b1638SMasahiro Yamada         dictid = adler32(0L, Z_NULL, 0);
1313221b1638SMasahiro Yamada         dictid = adler32(dictid, dictionary, dictLength);
1314221b1638SMasahiro Yamada         if (dictid != state->check)
1315221b1638SMasahiro Yamada             return Z_DATA_ERROR;
1316221b1638SMasahiro Yamada     }
1317221b1638SMasahiro Yamada 
1318221b1638SMasahiro Yamada     /* copy dictionary to window using updatewindow(), which will amend the
1319221b1638SMasahiro Yamada        existing dictionary if appropriate */
1320221b1638SMasahiro Yamada     ret = updatewindow(strm, dictionary + dictLength, dictLength);
1321221b1638SMasahiro Yamada     if (ret) {
1322221b1638SMasahiro Yamada         state->mode = MEM;
1323221b1638SMasahiro Yamada         return Z_MEM_ERROR;
1324221b1638SMasahiro Yamada     }
1325221b1638SMasahiro Yamada     state->havedict = 1;
1326221b1638SMasahiro Yamada     Tracev((stderr, "inflate:   dictionary set\n"));
1327221b1638SMasahiro Yamada     return Z_OK;
1328221b1638SMasahiro Yamada }
1329221b1638SMasahiro Yamada 
inflateGetHeader(z_streamp strm,gz_headerp head)1330fd39217aSManish Pandey int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) {
1331221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1332221b1638SMasahiro Yamada 
1333221b1638SMasahiro Yamada     /* check state */
1334221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1335221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1336221b1638SMasahiro Yamada     if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
1337221b1638SMasahiro Yamada 
1338221b1638SMasahiro Yamada     /* save header structure */
1339221b1638SMasahiro Yamada     state->head = head;
1340221b1638SMasahiro Yamada     head->done = 0;
1341221b1638SMasahiro Yamada     return Z_OK;
1342221b1638SMasahiro Yamada }
1343221b1638SMasahiro Yamada 
1344221b1638SMasahiro Yamada /*
1345221b1638SMasahiro Yamada    Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
1346221b1638SMasahiro Yamada    or when out of input.  When called, *have is the number of pattern bytes
1347221b1638SMasahiro Yamada    found in order so far, in 0..3.  On return *have is updated to the new
1348221b1638SMasahiro Yamada    state.  If on return *have equals four, then the pattern was found and the
1349221b1638SMasahiro Yamada    return value is how many bytes were read including the last byte of the
1350221b1638SMasahiro Yamada    pattern.  If *have is less than four, then the pattern has not been found
1351221b1638SMasahiro Yamada    yet and the return value is len.  In the latter case, syncsearch() can be
1352221b1638SMasahiro Yamada    called again with more data and the *have state.  *have is initialized to
1353221b1638SMasahiro Yamada    zero for the first call.
1354221b1638SMasahiro Yamada  */
syncsearch(unsigned FAR * have,const unsigned char FAR * buf,unsigned len)1355fd39217aSManish Pandey local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf,
1356fd39217aSManish Pandey                           unsigned len) {
1357221b1638SMasahiro Yamada     unsigned got;
1358221b1638SMasahiro Yamada     unsigned next;
1359221b1638SMasahiro Yamada 
1360221b1638SMasahiro Yamada     got = *have;
1361221b1638SMasahiro Yamada     next = 0;
1362221b1638SMasahiro Yamada     while (next < len && got < 4) {
1363221b1638SMasahiro Yamada         if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
1364221b1638SMasahiro Yamada             got++;
1365221b1638SMasahiro Yamada         else if (buf[next])
1366221b1638SMasahiro Yamada             got = 0;
1367221b1638SMasahiro Yamada         else
1368221b1638SMasahiro Yamada             got = 4 - got;
1369221b1638SMasahiro Yamada         next++;
1370221b1638SMasahiro Yamada     }
1371221b1638SMasahiro Yamada     *have = got;
1372221b1638SMasahiro Yamada     return next;
1373221b1638SMasahiro Yamada }
1374221b1638SMasahiro Yamada 
inflateSync(z_streamp strm)1375fd39217aSManish Pandey int ZEXPORT inflateSync(z_streamp strm) {
1376221b1638SMasahiro Yamada     unsigned len;               /* number of bytes to look at or looked at */
1377a194255dSDaniel Boulby     int flags;                  /* temporary to save header status */
1378221b1638SMasahiro Yamada     unsigned long in, out;      /* temporary to save total_in and total_out */
1379221b1638SMasahiro Yamada     unsigned char buf[4];       /* to restore bit buffer to byte string */
1380221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1381221b1638SMasahiro Yamada 
1382221b1638SMasahiro Yamada     /* check parameters */
1383221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1384221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1385221b1638SMasahiro Yamada     if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
1386221b1638SMasahiro Yamada 
1387221b1638SMasahiro Yamada     /* if first time, start search in bit buffer */
1388221b1638SMasahiro Yamada     if (state->mode != SYNC) {
1389221b1638SMasahiro Yamada         state->mode = SYNC;
1390*a8c877cbSChris Kay         state->hold >>= state->bits & 7;
1391221b1638SMasahiro Yamada         state->bits -= state->bits & 7;
1392221b1638SMasahiro Yamada         len = 0;
1393221b1638SMasahiro Yamada         while (state->bits >= 8) {
1394221b1638SMasahiro Yamada             buf[len++] = (unsigned char)(state->hold);
1395221b1638SMasahiro Yamada             state->hold >>= 8;
1396221b1638SMasahiro Yamada             state->bits -= 8;
1397221b1638SMasahiro Yamada         }
1398221b1638SMasahiro Yamada         state->have = 0;
1399221b1638SMasahiro Yamada         syncsearch(&(state->have), buf, len);
1400221b1638SMasahiro Yamada     }
1401221b1638SMasahiro Yamada 
1402221b1638SMasahiro Yamada     /* search available input */
1403221b1638SMasahiro Yamada     len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
1404221b1638SMasahiro Yamada     strm->avail_in -= len;
1405221b1638SMasahiro Yamada     strm->next_in += len;
1406221b1638SMasahiro Yamada     strm->total_in += len;
1407221b1638SMasahiro Yamada 
1408221b1638SMasahiro Yamada     /* return no joy or set up to restart inflate() on a new block */
1409221b1638SMasahiro Yamada     if (state->have != 4) return Z_DATA_ERROR;
1410a194255dSDaniel Boulby     if (state->flags == -1)
1411a194255dSDaniel Boulby         state->wrap = 0;    /* if no header yet, treat as raw */
1412a194255dSDaniel Boulby     else
1413a194255dSDaniel Boulby         state->wrap &= ~4;  /* no point in computing a check value now */
1414a194255dSDaniel Boulby     flags = state->flags;
1415221b1638SMasahiro Yamada     in = strm->total_in;  out = strm->total_out;
1416221b1638SMasahiro Yamada     inflateReset(strm);
1417221b1638SMasahiro Yamada     strm->total_in = in;  strm->total_out = out;
1418a194255dSDaniel Boulby     state->flags = flags;
1419221b1638SMasahiro Yamada     state->mode = TYPE;
1420221b1638SMasahiro Yamada     return Z_OK;
1421221b1638SMasahiro Yamada }
1422221b1638SMasahiro Yamada 
1423221b1638SMasahiro Yamada /*
1424221b1638SMasahiro Yamada    Returns true if inflate is currently at the end of a block generated by
1425221b1638SMasahiro Yamada    Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
1426221b1638SMasahiro Yamada    implementation to provide an additional safety check. PPP uses
1427221b1638SMasahiro Yamada    Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
1428221b1638SMasahiro Yamada    block. When decompressing, PPP checks that at the end of input packet,
1429221b1638SMasahiro Yamada    inflate is waiting for these length bytes.
1430221b1638SMasahiro Yamada  */
inflateSyncPoint(z_streamp strm)1431fd39217aSManish Pandey int ZEXPORT inflateSyncPoint(z_streamp strm) {
1432221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1433221b1638SMasahiro Yamada 
1434221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1435221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1436221b1638SMasahiro Yamada     return state->mode == STORED && state->bits == 0;
1437221b1638SMasahiro Yamada }
1438221b1638SMasahiro Yamada 
inflateCopy(z_streamp dest,z_streamp source)1439fd39217aSManish Pandey int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) {
1440221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1441221b1638SMasahiro Yamada     struct inflate_state FAR *copy;
1442221b1638SMasahiro Yamada     unsigned char FAR *window;
1443221b1638SMasahiro Yamada     unsigned wsize;
1444221b1638SMasahiro Yamada 
1445221b1638SMasahiro Yamada     /* check input */
1446221b1638SMasahiro Yamada     if (inflateStateCheck(source) || dest == Z_NULL)
1447221b1638SMasahiro Yamada         return Z_STREAM_ERROR;
1448221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)source->state;
1449221b1638SMasahiro Yamada 
1450221b1638SMasahiro Yamada     /* allocate space */
1451221b1638SMasahiro Yamada     copy = (struct inflate_state FAR *)
1452221b1638SMasahiro Yamada            ZALLOC(source, 1, sizeof(struct inflate_state));
1453221b1638SMasahiro Yamada     if (copy == Z_NULL) return Z_MEM_ERROR;
1454221b1638SMasahiro Yamada     window = Z_NULL;
1455221b1638SMasahiro Yamada     if (state->window != Z_NULL) {
1456221b1638SMasahiro Yamada         window = (unsigned char FAR *)
1457221b1638SMasahiro Yamada                  ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
1458221b1638SMasahiro Yamada         if (window == Z_NULL) {
1459221b1638SMasahiro Yamada             ZFREE(source, copy);
1460221b1638SMasahiro Yamada             return Z_MEM_ERROR;
1461221b1638SMasahiro Yamada         }
1462221b1638SMasahiro Yamada     }
1463221b1638SMasahiro Yamada 
1464221b1638SMasahiro Yamada     /* copy state */
1465221b1638SMasahiro Yamada     zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
1466221b1638SMasahiro Yamada     zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
1467221b1638SMasahiro Yamada     copy->strm = dest;
1468221b1638SMasahiro Yamada     if (state->lencode >= state->codes &&
1469221b1638SMasahiro Yamada         state->lencode <= state->codes + ENOUGH - 1) {
1470221b1638SMasahiro Yamada         copy->lencode = copy->codes + (state->lencode - state->codes);
1471221b1638SMasahiro Yamada         copy->distcode = copy->codes + (state->distcode - state->codes);
1472221b1638SMasahiro Yamada     }
1473221b1638SMasahiro Yamada     copy->next = copy->codes + (state->next - state->codes);
1474221b1638SMasahiro Yamada     if (window != Z_NULL) {
1475221b1638SMasahiro Yamada         wsize = 1U << state->wbits;
1476221b1638SMasahiro Yamada         zmemcpy(window, state->window, wsize);
1477221b1638SMasahiro Yamada     }
1478221b1638SMasahiro Yamada     copy->window = window;
1479221b1638SMasahiro Yamada     dest->state = (struct internal_state FAR *)copy;
1480221b1638SMasahiro Yamada     return Z_OK;
1481221b1638SMasahiro Yamada }
1482221b1638SMasahiro Yamada 
inflateUndermine(z_streamp strm,int subvert)1483fd39217aSManish Pandey int ZEXPORT inflateUndermine(z_streamp strm, int subvert) {
1484221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1485221b1638SMasahiro Yamada 
1486221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1487221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1488221b1638SMasahiro Yamada #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
1489221b1638SMasahiro Yamada     state->sane = !subvert;
1490221b1638SMasahiro Yamada     return Z_OK;
1491221b1638SMasahiro Yamada #else
1492221b1638SMasahiro Yamada     (void)subvert;
1493221b1638SMasahiro Yamada     state->sane = 1;
1494221b1638SMasahiro Yamada     return Z_DATA_ERROR;
1495221b1638SMasahiro Yamada #endif
1496221b1638SMasahiro Yamada }
1497221b1638SMasahiro Yamada 
inflateValidate(z_streamp strm,int check)1498fd39217aSManish Pandey int ZEXPORT inflateValidate(z_streamp strm, int check) {
1499221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1500221b1638SMasahiro Yamada 
1501221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
1502221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1503a194255dSDaniel Boulby     if (check && state->wrap)
1504221b1638SMasahiro Yamada         state->wrap |= 4;
1505221b1638SMasahiro Yamada     else
1506221b1638SMasahiro Yamada         state->wrap &= ~4;
1507221b1638SMasahiro Yamada     return Z_OK;
1508221b1638SMasahiro Yamada }
1509221b1638SMasahiro Yamada 
inflateMark(z_streamp strm)1510fd39217aSManish Pandey long ZEXPORT inflateMark(z_streamp strm) {
1511221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1512221b1638SMasahiro Yamada 
1513221b1638SMasahiro Yamada     if (inflateStateCheck(strm))
1514221b1638SMasahiro Yamada         return -(1L << 16);
1515221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1516221b1638SMasahiro Yamada     return (long)(((unsigned long)((long)state->back)) << 16) +
1517221b1638SMasahiro Yamada         (state->mode == COPY ? state->length :
1518221b1638SMasahiro Yamada             (state->mode == MATCH ? state->was - state->length : 0));
1519221b1638SMasahiro Yamada }
1520221b1638SMasahiro Yamada 
inflateCodesUsed(z_streamp strm)1521fd39217aSManish Pandey unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) {
1522221b1638SMasahiro Yamada     struct inflate_state FAR *state;
1523221b1638SMasahiro Yamada     if (inflateStateCheck(strm)) return (unsigned long)-1;
1524221b1638SMasahiro Yamada     state = (struct inflate_state FAR *)strm->state;
1525221b1638SMasahiro Yamada     return (unsigned long)(state->next - state->codes);
1526221b1638SMasahiro Yamada }
1527