1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* inflate.c -- zlib decompression
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Copyright (C) 1995-2012 Mark Adler
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * For conditions of distribution and use, see copyright notice in zlib.h
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * Change history:
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1.2.beta0    24 Nov 2002
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - First version -- complete rewrite of inflate to simplify code, avoid
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *   creation of window when not needed, minimize use of window when it is
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *   needed, make inffast.c even faster, implement gzip decoding, and to
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *   improve code readability and style over the previous zlib inflate code
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1.2.beta1    25 Nov 2002
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Use pointers for available input and output checking in inffast.c
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Remove input and output counters in inffast.c
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Remove unnecessary second byte pull from length extra in inffast.c
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Unroll direct copy to three copies per loop in inffast.c
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1.2.beta2    4 Dec 2002
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Change external routine names to reduce potential conflicts
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Correct filename to inffixed.h for fixed tables in inflate.c
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Make hbuf[] unsigned char to match parameter type in inflate.c
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *   to avoid negation problem on Alphas (64 bit) in inflate.c
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1.2.beta3    22 Dec 2002
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Add comments on state->bits assertion in inffast.c
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Add comments on op field in inftrees.h
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Fix bug in reuse of allocated window after inflateReset()
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Remove bit fields--back to byte structure for speed
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Use local copies of stream next and avail values, as well as local bit
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *   buffer and bit count in inflate()--for speed when inflate_fast() not used
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1.2.beta4    1 Jan 2003
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Move a comment on output buffer sizes from inffast.c to inflate.c
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Add comments in inffast.c to introduce the inflate_fast() routine
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Rearrange window copies in inflate_fast() for speed and simplification
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Unroll last copy for window match in inflate_fast()
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Use local copies of window variables in inflate_fast() for speed
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Pull out common wnext == 0 case for speed in inflate_fast()
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Make op and len in inflate_fast() unsigned for consistency
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Add FAR to lcode and dcode declarations in inflate_fast()
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Simplified bad distance check in inflate_fast()
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *   source file infback.c to provide a call-back interface to inflate for
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *   programs like gzip and unzip -- uses window as output buffer to avoid
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *   window copying
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1.2.beta5    1 Jan 2003
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Improved inflateBack() interface to allow the caller to provide initial
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *   input in strm.
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Fixed stored blocks bug in inflateBack()
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1.2.beta6    4 Jan 2003
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Added comments in inffast.c on effectiveness of POSTINC
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Typecasting all around to reduce compiler warnings
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Changed loops from while (1) or do {} while (1) to for (;;), again to
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *   make compilers happy
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Changed type of window in inflateBackInit() to unsigned char *
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1.2.beta7    27 Jan 2003
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Changed many types to unsigned or unsigned short to avoid warnings
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Added inflateCopy() function
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 1.2.0        9 Mar 2003
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Changed inflateBack() interface to provide separate opaque descriptors
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *   for the in() and out() functions
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Changed inflateBack() argument and in_func typedef to swap the length
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *   and buffer address return values for the input function
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * - Check next_in and next_out for Z_NULL on entry to inflate()
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "zutil.h"
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "inftrees.h"
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "inflate.h"
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "inffast.h"
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef MAKEFIXED
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#  ifndef BUILDFIXED
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#    define BUILDFIXED
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#  endif
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* function prototypes */
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovlocal void fixedtables OF((struct inflate_state FAR *state));
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovlocal int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                           unsigned copy));
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef BUILDFIXED
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   void makefixed OF((void));
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovlocal unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              unsigned len));
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflateResetKeep(
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm)
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strm->total_in = strm->total_out = state->total = 0;
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strm->msg = Z_NULL;
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->wrap)        /* to support ill-conceived Java test suite */
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strm->adler = state->wrap & 1;
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->mode = HEAD;
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->last = 0;
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->havedict = 0;
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->dmax = 32768U;
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->head = Z_NULL;
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->hold = 0;
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->bits = 0;
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->lencode = state->distcode = state->next = state->codes;
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->sane = 1;
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->back = -1;
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Tracev((stderr, "inflate: reset\n"));
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return Z_OK;
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflateReset(
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm)
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->wsize = 0;
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->whave = 0;
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->wnext = 0;
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return inflateResetKeep(strm);
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflateReset2(
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm,
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint windowBits)
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int wrap;
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* get the state */
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* extract wrap request from windowBits parameter */
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (windowBits < 0) {
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        wrap = 0;
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        windowBits = -windowBits;
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else {
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        wrap = (windowBits >> 4) + 1;
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef GUNZIP
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (windowBits < 48)
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            windowBits &= 15;
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* set number of window bits, free window if different */
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (windowBits && (windowBits < 8 || windowBits > 15))
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return Z_STREAM_ERROR;
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ZFREE(strm, state->window);
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->window = Z_NULL;
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* update state and reset the rest of it */
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->wrap = wrap;
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->wbits = (unsigned)windowBits;
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return inflateReset(strm);
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflateInit2_(
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm,
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint windowBits,
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst char *version,
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint stream_size)
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int ret;
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        stream_size != (int)(sizeof(z_stream)))
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return Z_VERSION_ERROR;
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL) return Z_STREAM_ERROR;
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strm->msg = Z_NULL;                 /* in case we return an error */
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm->zalloc == (alloc_func)0) {
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef Z_SOLO
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return Z_STREAM_ERROR;
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strm->zalloc = zcalloc;
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strm->opaque = (voidpf)0;
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm->zfree == (free_func)0)
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef Z_SOLO
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return Z_STREAM_ERROR;
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strm->zfree = zcfree;
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ZALLOC(strm, 1, sizeof(struct inflate_state));
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state == Z_NULL) return Z_MEM_ERROR;
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Tracev((stderr, "inflate: allocated\n"));
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strm->state = (struct internal_state FAR *)state;
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->window = Z_NULL;
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ret = inflateReset2(strm, windowBits);
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ret != Z_OK) {
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ZFREE(strm, state);
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strm->state = Z_NULL;
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ret;
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflateInit_(
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm,
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst char *version,
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint stream_size)
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflatePrime(
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm,
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint bits,
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint value)
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bits < 0) {
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->hold = 0;
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->bits = 0;
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return Z_OK;
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    value &= (1L << bits) - 1;
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->hold += value << state->bits;
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->bits += bits;
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return Z_OK;
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   Return state with length and distance decoding tables and index sizes set to
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   If BUILDFIXED is defined, then instead this routine builds the tables the
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   first time it's called, and returns those tables the first time and
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   thereafter.  This reduces the size of the code by about 2K bytes, in
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   exchange for a little execution time.  However, BUILDFIXED should not be
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   used for threaded applications, since the rewriting of the tables and virgin
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   may not be thread-safe.
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovlocal void fixedtables(
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstruct inflate_state FAR *state)
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef BUILDFIXED
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static int virgin = 1;
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static code *lenfix, *distfix;
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static code fixed[544];
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* build fixed huffman tables if first call (may not be thread safe) */
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (virgin) {
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        unsigned sym, bits;
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        static code *next;
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        /* literal/length table */
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        sym = 0;
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (sym < 144) state->lens[sym++] = 8;
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (sym < 256) state->lens[sym++] = 9;
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (sym < 280) state->lens[sym++] = 7;
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (sym < 288) state->lens[sym++] = 8;
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        next = fixed;
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        lenfix = next;
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bits = 9;
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        /* distance table */
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        sym = 0;
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (sym < 32) state->lens[sym++] = 5;
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        distfix = next;
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bits = 5;
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        /* do this just once */
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        virgin = 0;
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !BUILDFIXED */
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#   include "inffixed.h"
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* BUILDFIXED */
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->lencode = lenfix;
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->lenbits = 9;
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->distcode = distfix;
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->distbits = 5;
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef MAKEFIXED
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <stdio.h>
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   those tables to stdout, which would be piped to inffixed.h.  A small program
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   can simply call makefixed to do this:
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    void makefixed(void);
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int main(void)
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        makefixed();
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   Then that can be linked with zlib built with MAKEFIXED defined and run:
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    a.out > inffixed.h
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid makefixed()
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned low, size;
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state state;
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    fixedtables(&state);
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    puts("    /* inffixed.h -- table for decoding fixed codes");
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    puts("     * Generated automatically by makefixed().");
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    puts("     */");
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    puts("");
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    puts("    /* WARNING: this file should *not* be used by applications.");
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    puts("       It is part of the implementation of this library and is");
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    puts("       subject to change. Applications should only use zlib.h.");
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    puts("     */");
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    puts("");
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    size = 1U << 9;
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    printf("    static const code lenfix[%u] = {", size);
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    low = 0;
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (;;) {
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ((low % 7) == 0) printf("\n        ");
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               state.lencode[low].bits, state.lencode[low].val);
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (++low == size) break;
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        putchar(',');
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    puts("\n    };");
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    size = 1U << 5;
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    printf("\n    static const code distfix[%u] = {", size);
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    low = 0;
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (;;) {
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ((low % 6) == 0) printf("\n        ");
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               state.distcode[low].val);
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (++low == size) break;
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        putchar(',');
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    puts("\n    };");
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* MAKEFIXED */
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   Update the window with the last wsize (normally 32K) bytes written before
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   returning.  If window does not exist yet, create it.  This is only called
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   when a window is already in use, or when output has been written during this
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   inflate call, but the end of the deflate stream has not been reached yet.
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   It is also called to create a window for dictionary data when a dictionary
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   is loaded.
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   Providing output buffers larger than 32K to inflate() should provide a speed
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   advantage, since only the last 32K of output is copied to the sliding window
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   upon return from inflate(), and since all distances after the first 32K of
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   output will fall in the output data, making match copies simpler and faster.
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   The advantage may be dependent on the size of the processor's data caches.
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovlocal int updatewindow(
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm,
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst Bytef *end,
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovunsigned copy)
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned dist;
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* if it hasn't been done already, allocate space for the window */
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->window == Z_NULL) {
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->window = (unsigned char FAR *)
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        ZALLOC(strm, 1U << state->wbits,
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                               sizeof(unsigned char));
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (state->window == Z_NULL) return 1;
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* if window not in use yet, initialize */
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->wsize == 0) {
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->wsize = 1U << state->wbits;
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->wnext = 0;
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->whave = 0;
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* copy state->wsize or less output bytes into the circular window */
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (copy >= state->wsize) {
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        zmemcpy(state->window, end - state->wsize, state->wsize);
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->wnext = 0;
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->whave = state->wsize;
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    else {
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dist = state->wsize - state->wnext;
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dist > copy) dist = copy;
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        zmemcpy(state->window + state->wnext, end - copy, dist);
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        copy -= dist;
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (copy) {
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            zmemcpy(state->window, end - copy, copy);
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->wnext = copy;
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->whave = state->wsize;
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else {
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->wnext += dist;
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->wnext == state->wsize) state->wnext = 0;
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->whave < state->wsize) state->whave += dist;
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Macros for inflate(): */
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* check function to use adler32() for zlib or crc32() for gzip */
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef GUNZIP
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#  define UPDATE(check, buf, len) \
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#  define UPDATE(check, buf, len) adler32(check, buf, len)
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* check macros for header crc */
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef GUNZIP
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#  define CRC2(check, word) \
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    do { \
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        hbuf[0] = (unsigned char)(word); \
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        hbuf[1] = (unsigned char)((word) >> 8); \
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        check = crc32(check, hbuf, 2); \
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } while (0)
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#  define CRC4(check, word) \
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    do { \
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        hbuf[0] = (unsigned char)(word); \
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        hbuf[1] = (unsigned char)((word) >> 8); \
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        hbuf[2] = (unsigned char)((word) >> 16); \
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        hbuf[3] = (unsigned char)((word) >> 24); \
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        check = crc32(check, hbuf, 4); \
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } while (0)
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Load registers with state in inflate() for speed */
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define LOAD() \
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    do { \
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        put = strm->next_out; \
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        left = strm->avail_out; \
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        next = strm->next_in; \
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        have = strm->avail_in; \
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        hold = state->hold; \
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bits = state->bits; \
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } while (0)
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Restore state from registers in inflate() */
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RESTORE() \
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    do { \
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strm->next_out = put; \
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strm->avail_out = left; \
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strm->next_in = next; \
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strm->avail_in = have; \
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->hold = hold; \
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->bits = bits; \
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } while (0)
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Clear the input bit accumulator */
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define INITBITS() \
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    do { \
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        hold = 0; \
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bits = 0; \
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } while (0)
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Get a byte of input into the bit accumulator, or return from inflate()
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   if there is no input available. */
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define PULLBYTE() \
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    do { \
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (have == 0) goto inf_leave; \
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        have--; \
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        hold += (unsigned long)(*next++) << bits; \
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bits += 8; \
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } while (0)
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Assure that there are at least n bits in the bit accumulator.  If there is
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   not enough available input to do that, then return from inflate(). */
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define NEEDBITS(n) \
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    do { \
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (bits < (unsigned)(n)) \
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            PULLBYTE(); \
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } while (0)
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Return the low n bits of the bit accumulator (n < 16) */
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define BITS(n) \
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ((unsigned)hold & ((1U << (n)) - 1))
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Remove n bits from the bit accumulator */
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define DROPBITS(n) \
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    do { \
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        hold >>= (n); \
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bits -= (unsigned)(n); \
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } while (0)
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Remove zero to seven bits as needed to go to a byte boundary */
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define BYTEBITS() \
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    do { \
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        hold >>= bits & 7; \
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bits -= bits & 7; \
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } while (0)
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   inflate() uses a state machine to process as much input data and generate as
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   much output data as possible before returning.  The state machine is
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   structured roughly as follows:
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (;;) switch (state) {
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ...
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    case STATEn:
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (not enough input data or output space to make progress)
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ... make progress ...
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state = STATEm;
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        break;
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ...
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   so when inflate() is called again, the same case is attempted again, and
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   if the appropriate resources are provided, the machine proceeds to the
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   next state.  The NEEDBITS() macro is usually the way the state evaluates
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   whether it can proceed or should return.  NEEDBITS() does the return if
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   the requested bits are not available.  The typical use of the BITS macros
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   is:
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        NEEDBITS(n);
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ... do something with BITS(n) ...
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        DROPBITS(n);
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   where NEEDBITS(n) either returns from inflate() if there isn't enough
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   input left to load n bits into the accumulator, or it continues.  BITS(n)
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   the low n bits off the accumulator.  INITBITS() clears the accumulator
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   and sets the number of available bits to zero.  BYTEBITS() discards just
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   if there is no input available.  The decoding of variable length codes uses
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   PULLBYTE() directly in order to pull just enough bytes to decode the next
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   code, and no more.
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   Some states loop until they get enough input, making sure that enough
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   state information is maintained to continue the loop where it left off
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   if NEEDBITS() returns in the loop.  For example, want, need, and keep
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   would all have to actually be part of the saved state in case NEEDBITS()
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   returns:
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    case STATEw:
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (want < need) {
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NEEDBITS(n);
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            keep[want++] = BITS(n);
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            DROPBITS(n);
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state = STATEx;
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    case STATEx:
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   As shown above, if the next state is also the next case, then the break
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   is omitted.
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   A state may also return if there is not enough output space available to
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   complete that state.  Those states are copying stored data, writing a
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   literal byte, and copying a matching string.
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   When returning, a "goto inf_leave" is used to update the total counters,
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   update the check value, and determine whether any progress has been made
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   during that inflate() call in order to return the proper return code.
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   Progress is defined as a change in either strm->avail_in or strm->avail_out.
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   When there is a window, goto inf_leave will update the window with the last
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   output written.  If a goto inf_leave occurs in the middle of decompression
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   and there is no window currently, goto inf_leave will create one and copy
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   output to the window for the next call of inflate().
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   In this implementation, the flush parameter of inflate() only affects the
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   return code (per zlib.h).  inflate() always writes as much as possible to
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   strm->next_out, given the space available and the provided input--the effect
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   the allocation of and copying into a sliding window until necessary, which
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   provides the effect documented in zlib.h for Z_FINISH when the entire input
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   stream available.  So the only thing the flush parameter actually does is:
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   will return Z_BUF_ERROR if it has not reached the end of the stream.
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflate(
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm,
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint flush)
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    z_const unsigned char FAR *next;    /* next input */
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned char FAR *put;     /* next output */
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned have, left;        /* available input and output */
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned long hold;         /* bit buffer */
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned bits;              /* bits in bit buffer */
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned in, out;           /* save starting available input and output */
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned copy;              /* number of stored or match bytes to copy */
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned char FAR *from;    /* where to copy match bytes from */
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    code here;                  /* current decoding table entry */
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    code last;                  /* parent table entry */
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned len;               /* length to copy for repeats, bits to drop */
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int ret;                    /* return code */
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef GUNZIP
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static const unsigned short order[19] = /* permutation of code lengths */
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        (strm->next_in == Z_NULL && strm->avail_in != 0))
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return Z_STREAM_ERROR;
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    LOAD();
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    in = have;
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    out = left;
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ret = Z_OK;
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (;;)
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        switch (state->mode) {
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case HEAD:
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->wrap == 0) {
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = TYPEDO;
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NEEDBITS(16);
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef GUNZIP
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->check = crc32(0L, Z_NULL, 0);
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                CRC2(state->check, hold);
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                INITBITS();
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = FLAGS;
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->flags = 0;           /* expect zlib header */
655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->head != Z_NULL)
656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->head->done = -1;
657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (
660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ((BITS(8) << 8) + (hold >> 8)) % 31) {
662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"incorrect header check";
663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (BITS(4) != Z_DEFLATED) {
667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"unknown compression method";
668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            DROPBITS(4);
672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            len = BITS(4) + 8;
673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->wbits == 0)
674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->wbits = len;
675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            else if (len > state->wbits) {
676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"invalid window size";
677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->dmax = 1U << len;
681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            Tracev((stderr, "inflate:   zlib header ok\n"));
682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            strm->adler = state->check = adler32(0L, Z_NULL, 0);
683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = hold & 0x200 ? DICTID : TYPE;
684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            INITBITS();
685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef GUNZIP
687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case FLAGS:
688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NEEDBITS(16);
689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->flags = (int)(hold);
690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((state->flags & 0xff) != Z_DEFLATED) {
691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"unknown compression method";
692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->flags & 0xe000) {
696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"unknown header flags set";
697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->head != Z_NULL)
701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->head->text = (int)((hold >> 8) & 1);
702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->flags & 0x0200) CRC2(state->check, hold);
703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            INITBITS();
704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = TIME;
705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case TIME:
706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NEEDBITS(32);
707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->head != Z_NULL)
708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->head->time = hold;
709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->flags & 0x0200) CRC4(state->check, hold);
710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            INITBITS();
711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = OS;
712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case OS:
713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NEEDBITS(16);
714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->head != Z_NULL) {
715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->head->xflags = (int)(hold & 0xff);
716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->head->os = (int)(hold >> 8);
717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->flags & 0x0200) CRC2(state->check, hold);
719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            INITBITS();
720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = EXLEN;
721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case EXLEN:
722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->flags & 0x0400) {
723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NEEDBITS(16);
724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->length = (unsigned)(hold);
725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (state->head != Z_NULL)
726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    state->head->extra_len = (unsigned)hold;
727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (state->flags & 0x0200) CRC2(state->check, hold);
728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                INITBITS();
729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            else if (state->head != Z_NULL)
731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->head->extra = Z_NULL;
732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = EXTRA;
733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case EXTRA:
734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->flags & 0x0400) {
735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                copy = state->length;
736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (copy > have) copy = have;
737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (copy) {
738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (state->head != Z_NULL &&
739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        state->head->extra != Z_NULL) {
740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        len = state->head->extra_len - state->length;
741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        zmemcpy(state->head->extra + len, next,
742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                len + copy > state->head->extra_max ?
743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                state->head->extra_max - len : copy);
744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (state->flags & 0x0200)
746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        state->check = crc32(state->check, next, copy);
747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    have -= copy;
748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    next += copy;
749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    state->length -= copy;
750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (state->length) goto inf_leave;
752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->length = 0;
754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = NAME;
755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case NAME:
756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->flags & 0x0800) {
757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (have == 0) goto inf_leave;
758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                copy = 0;
759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                do {
760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    len = (unsigned)(next[copy++]);
761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (state->head != Z_NULL &&
762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            state->head->name != Z_NULL &&
763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            state->length < state->head->name_max)
764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        state->head->name[state->length++] = len;
765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } while (len && copy < have);
766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (state->flags & 0x0200)
767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    state->check = crc32(state->check, next, copy);
768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                have -= copy;
769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                next += copy;
770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (len) goto inf_leave;
771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            else if (state->head != Z_NULL)
773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->head->name = Z_NULL;
774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->length = 0;
775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = COMMENT;
776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case COMMENT:
777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->flags & 0x1000) {
778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (have == 0) goto inf_leave;
779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                copy = 0;
780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                do {
781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    len = (unsigned)(next[copy++]);
782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (state->head != Z_NULL &&
783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            state->head->comment != Z_NULL &&
784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            state->length < state->head->comm_max)
785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        state->head->comment[state->length++] = len;
786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } while (len && copy < have);
787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (state->flags & 0x0200)
788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    state->check = crc32(state->check, next, copy);
789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                have -= copy;
790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                next += copy;
791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (len) goto inf_leave;
792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            else if (state->head != Z_NULL)
794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->head->comment = Z_NULL;
795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = HCRC;
796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case HCRC:
797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->flags & 0x0200) {
798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NEEDBITS(16);
799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (hold != (state->check & 0xffff)) {
800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    strm->msg = (char *)"header crc mismatch";
801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    state->mode = BAD;
802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                INITBITS();
805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->head != Z_NULL) {
807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->head->hcrc = (int)((state->flags >> 9) & 1);
808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->head->done = 1;
809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            strm->adler = state->check = crc32(0L, Z_NULL, 0);
811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = TYPE;
812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case DICTID:
815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NEEDBITS(32);
816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            strm->adler = state->check = ZSWAP32(hold);
817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            INITBITS();
818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = DICT;
819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case DICT:
820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->havedict == 0) {
821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                RESTORE();
822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return Z_NEED_DICT;
823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            strm->adler = state->check = adler32(0L, Z_NULL, 0);
825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = TYPE;
826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case TYPE:
827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case TYPEDO:
829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->last) {
830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                BYTEBITS();
831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = CHECK;
832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NEEDBITS(3);
835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->last = BITS(1);
836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            DROPBITS(1);
837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            switch (BITS(2)) {
838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 0:                             /* stored block */
839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                Tracev((stderr, "inflate:     stored block%s\n",
840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        state->last ? " (last)" : ""));
841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = STORED;
842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 1:                             /* fixed block */
844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                fixedtables(state);
845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                Tracev((stderr, "inflate:     fixed codes block%s\n",
846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        state->last ? " (last)" : ""));
847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = LEN_;             /* decode codes */
848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (flush == Z_TREES) {
849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    DROPBITS(2);
850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    goto inf_leave;
851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 2:                             /* dynamic block */
854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                Tracev((stderr, "inflate:     dynamic codes block%s\n",
855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        state->last ? " (last)" : ""));
856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = TABLE;
857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            case 3:
859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"invalid block type";
860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            DROPBITS(2);
863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case STORED:
865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            BYTEBITS();                         /* go to byte boundary */
866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NEEDBITS(32);
867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"invalid stored block lengths";
869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->length = (unsigned)hold & 0xffff;
873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            Tracev((stderr, "inflate:       stored length %u\n",
874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    state->length));
875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            INITBITS();
876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = COPY_;
877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (flush == Z_TREES) goto inf_leave;
878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case COPY_:
879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = COPY;
880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case COPY:
881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            copy = state->length;
882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (copy) {
883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (copy > have) copy = have;
884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (copy > left) copy = left;
885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (copy == 0) goto inf_leave;
886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                zmemcpy(put, next, copy);
887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                have -= copy;
888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                next += copy;
889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                left -= copy;
890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                put += copy;
891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->length -= copy;
892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            Tracev((stderr, "inflate:       stored end\n"));
895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = TYPE;
896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case TABLE:
898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            NEEDBITS(14);
899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->nlen = BITS(5) + 257;
900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            DROPBITS(5);
901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->ndist = BITS(5) + 1;
902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            DROPBITS(5);
903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->ncode = BITS(4) + 4;
904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            DROPBITS(4);
905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef PKZIP_BUG_WORKAROUND
906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->nlen > 286 || state->ndist > 30) {
907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"too many length or distance symbols";
908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            Tracev((stderr, "inflate:       table sizes ok\n"));
913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->have = 0;
914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = LENLENS;
915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case LENLENS:
916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            while (state->have < state->ncode) {
917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NEEDBITS(3);
918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->lens[order[state->have++]] = (unsigned short)BITS(3);
919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                DROPBITS(3);
920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            while (state->have < 19)
922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->lens[order[state->have++]] = 0;
923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->next = state->codes;
924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->lencode = (const code FAR *)(state->next);
925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->lenbits = 7;
926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ret = inflate_table(CODES, state->lens, 19, &(state->next),
927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                &(state->lenbits), state->work);
928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (ret) {
929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"invalid code lengths set";
930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            Tracev((stderr, "inflate:       code lengths ok\n"));
934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->have = 0;
935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = CODELENS;
936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case CODELENS:
937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            while (state->have < state->nlen + state->ndist) {
938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (;;) {
939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    here = state->lencode[BITS(state->lenbits)];
940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if ((unsigned)(here.bits) <= bits) break;
941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    PULLBYTE();
942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (here.val < 16) {
944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    DROPBITS(here.bits);
945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    state->lens[state->have++] = here.val;
946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                else {
948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (here.val == 16) {
949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        NEEDBITS(here.bits + 2);
950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        DROPBITS(here.bits);
951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        if (state->have == 0) {
952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            strm->msg = (char *)"invalid bit length repeat";
953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            state->mode = BAD;
954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            break;
955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        }
956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        len = state->lens[state->have - 1];
957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        copy = 3 + BITS(2);
958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        DROPBITS(2);
959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    else if (here.val == 17) {
961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        NEEDBITS(here.bits + 3);
962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        DROPBITS(here.bits);
963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        len = 0;
964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        copy = 3 + BITS(3);
965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        DROPBITS(3);
966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    else {
968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        NEEDBITS(here.bits + 7);
969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        DROPBITS(here.bits);
970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        len = 0;
971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        copy = 11 + BITS(7);
972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        DROPBITS(7);
973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (state->have + copy > state->nlen + state->ndist) {
975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        strm->msg = (char *)"invalid bit length repeat";
976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        state->mode = BAD;
977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        break;
978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    while (copy--)
980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        state->lens[state->have++] = (unsigned short)len;
981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            /* handle error breaks in while */
985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->mode == BAD) break;
986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            /* check for end-of-block code (better have one) */
988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->lens[256] == 0) {
989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"invalid code -- missing end-of-block";
990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            /* build code tables -- note: do not change the lenbits or distbits
995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               values here (9 and 6) without reading the comments in inftrees.h
996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov               concerning the ENOUGH constants, which depend on those values */
997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->next = state->codes;
998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->lencode = (const code FAR *)(state->next);
999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->lenbits = 9;
1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                &(state->lenbits), state->work);
1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (ret) {
1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"invalid literal/lengths set";
1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->distcode = (const code FAR *)(state->next);
1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->distbits = 6;
1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            &(state->next), &(state->distbits), state->work);
1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (ret) {
1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"invalid distances set";
1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            Tracev((stderr, "inflate:       codes ok\n"));
1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = LEN_;
1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (flush == Z_TREES) goto inf_leave;
1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case LEN_:
1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = LEN;
1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case LEN:
1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (have >= 6 && left >= 258) {
1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                RESTORE();
1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                inflate_fast(strm, out);
1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                LOAD();
1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (state->mode == TYPE)
1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    state->back = -1;
1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->back = 0;
1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (;;) {
1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                here = state->lencode[BITS(state->lenbits)];
1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if ((unsigned)(here.bits) <= bits) break;
1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                PULLBYTE();
1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (here.op && (here.op & 0xf0) == 0) {
1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                last = here;
1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (;;) {
1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    here = state->lencode[last.val +
1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            (BITS(last.bits + last.op) >> last.bits)];
1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if ((unsigned)(last.bits + here.bits) <= bits) break;
1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    PULLBYTE();
1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                DROPBITS(last.bits);
1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->back += last.bits;
1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            DROPBITS(here.bits);
1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->back += here.bits;
1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->length = (unsigned)here.val;
1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((int)(here.op) == 0) {
1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        "inflate:         literal '%c'\n" :
1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        "inflate:         literal 0x%02x\n", here.val));
1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = LIT;
1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (here.op & 32) {
1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                Tracevv((stderr, "inflate:         end of block\n"));
1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->back = -1;
1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = TYPE;
1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (here.op & 64) {
1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"invalid literal/length code";
1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->extra = (unsigned)(here.op) & 15;
1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = LENEXT;
1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case LENEXT:
1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->extra) {
1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NEEDBITS(state->extra);
1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->length += BITS(state->extra);
1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                DROPBITS(state->extra);
1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->back += state->extra;
1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            Tracevv((stderr, "inflate:         length %u\n", state->length));
1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->was = state->length;
1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = DIST;
1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case DIST:
1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (;;) {
1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                here = state->distcode[BITS(state->distbits)];
1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if ((unsigned)(here.bits) <= bits) break;
1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                PULLBYTE();
1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if ((here.op & 0xf0) == 0) {
1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                last = here;
1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (;;) {
1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    here = state->distcode[last.val +
1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            (BITS(last.bits + last.op) >> last.bits)];
1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if ((unsigned)(last.bits + here.bits) <= bits) break;
1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    PULLBYTE();
1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                DROPBITS(last.bits);
1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->back += last.bits;
1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            DROPBITS(here.bits);
1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->back += here.bits;
1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (here.op & 64) {
1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"invalid distance code";
1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->offset = (unsigned)here.val;
1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->extra = (unsigned)(here.op) & 15;
1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = DISTEXT;
1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case DISTEXT:
1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->extra) {
1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NEEDBITS(state->extra);
1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->offset += BITS(state->extra);
1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                DROPBITS(state->extra);
1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->back += state->extra;
1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef INFLATE_STRICT
1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->offset > state->dmax) {
1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->msg = (char *)"invalid distance too far back";
1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->mode = BAD;
1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = MATCH;
1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case MATCH:
1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (left == 0) goto inf_leave;
1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            copy = out - left;
1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->offset > copy) {         /* copy from window */
1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                copy = state->offset - copy;
1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (copy > state->whave) {
1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (state->sane) {
1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        strm->msg = (char *)"invalid distance too far back";
1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        state->mode = BAD;
1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        break;
1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    Trace((stderr, "inflate.c too far\n"));
1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    copy -= state->whave;
1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (copy > state->length) copy = state->length;
1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (copy > left) copy = left;
1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    left -= copy;
1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    state->length -= copy;
1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    do {
1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        *put++ = 0;
1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } while (--copy);
1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (state->length == 0) state->mode = LEN;
1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (copy > state->wnext) {
1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    copy -= state->wnext;
1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    from = state->window + (state->wsize - copy);
1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                else
1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    from = state->window + (state->wnext - copy);
1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (copy > state->length) copy = state->length;
1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            else {                              /* copy from output */
1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                from = put - state->offset;
1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                copy = state->length;
1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (copy > left) copy = left;
1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            left -= copy;
1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->length -= copy;
1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            do {
1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                *put++ = *from++;
1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } while (--copy);
1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->length == 0) state->mode = LEN;
1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case LIT:
1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (left == 0) goto inf_leave;
1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            *put++ = (unsigned char)(state->length);
1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            left--;
1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = LEN;
1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case CHECK:
1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->wrap) {
1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NEEDBITS(32);
1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                out -= left;
1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                strm->total_out += out;
1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->total += out;
1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (out)
1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    strm->adler = state->check =
1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        UPDATE(state->check, put - out, out);
1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                out = left;
1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if ((
1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef GUNZIP
1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     state->flags ? hold :
1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                     ZSWAP32(hold)) != state->check) {
1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    strm->msg = (char *)"incorrect data check";
1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    state->mode = BAD;
1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                INITBITS();
1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                Tracev((stderr, "inflate:   check matches trailer\n"));
1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef GUNZIP
1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = LENGTH;
1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case LENGTH:
1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (state->wrap && state->flags) {
1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                NEEDBITS(32);
1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (hold != (state->total & 0xffffffffUL)) {
1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    strm->msg = (char *)"incorrect length check";
1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    state->mode = BAD;
1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    break;
1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                INITBITS();
1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                Tracev((stderr, "inflate:   length matches trailer\n"));
1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = DONE;
1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case DONE:
1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ret = Z_STREAM_END;
1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            goto inf_leave;
1214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case BAD:
1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ret = Z_DATA_ERROR;
1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            goto inf_leave;
1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case MEM:
1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return Z_MEM_ERROR;
1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case SYNC:
1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        default:
1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return Z_STREAM_ERROR;
1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /*
1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       Return from inflate(), updating the total counts and the check value.
1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       If there was no progress during the inflate() call, return a buffer
1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       error.  Call updatewindow() to create and/or update the window state.
1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       Note: a memory error from inflate() is non-recoverable.
1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov     */
1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  inf_leave:
1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    RESTORE();
1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            (state->mode < CHECK || flush != Z_FINISH)))
1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->mode = MEM;
1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return Z_MEM_ERROR;
1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    in -= strm->avail_in;
1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    out -= strm->avail_out;
1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strm->total_in += in;
1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strm->total_out += out;
1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->total += out;
1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->wrap && out)
1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        strm->adler = state->check =
1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            UPDATE(state->check, strm->next_out - out, out);
1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strm->data_type = state->bits + (state->last ? 64 : 0) +
1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      (state->mode == TYPE ? 128 : 0) +
1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ret = Z_BUF_ERROR;
1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ret;
1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflateEnd(
1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm)
1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return Z_STREAM_ERROR;
1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->window != Z_NULL) ZFREE(strm, state->window);
1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ZFREE(strm, strm->state);
1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strm->state = Z_NULL;
1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Tracev((stderr, "inflate: end\n"));
1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return Z_OK;
1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflateGetDictionary(
1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm,
1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovBytef *dictionary,
1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovuInt *dictLength)
1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* check state */
1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* copy dictionary */
1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->whave && dictionary != Z_NULL) {
1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        zmemcpy(dictionary, state->window + state->wnext,
1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->whave - state->wnext);
1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        zmemcpy(dictionary + state->whave - state->wnext,
1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                state->window, state->wnext);
1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dictLength != Z_NULL)
1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        *dictLength = state->whave;
1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return Z_OK;
1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflateSetDictionary(
1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm,
1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst Bytef *dictionary,
1294ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovuInt dictLength)
1295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
1297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned long dictid;
1298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int ret;
1299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    dictid = 0;
1301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* check state */
1302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
1304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->wrap != 0 && state->mode != DICT)
1305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return Z_STREAM_ERROR;
1306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* check for correct dictionary identifier */
1308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->mode == DICT) {
1309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dictid = adler32(0L, Z_NULL, 0);
1310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dictid = adler32(dictid, dictionary, dictLength);
1311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dictid != state->check)
1312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return Z_DATA_ERROR;
1313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* copy dictionary to window using updatewindow(), which will amend the
1316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov       existing dictionary if appropriate */
1317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ret = updatewindow(strm, dictionary + dictLength, dictLength);
1318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ret) {
1319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->mode = MEM;
1320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return Z_MEM_ERROR;
1321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->havedict = 1;
1323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Tracev((stderr, "inflate:   dictionary set\n"));
1324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return Z_OK;
1325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflateGetHeader(
1328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm,
1329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovgz_headerp head)
1330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
1332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* check state */
1334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
1336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
1337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* save header structure */
1339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->head = head;
1340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    head->done = 0;
1341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return Z_OK;
1342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*
1345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
1346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   or when out of input.  When called, *have is the number of pattern bytes
1347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   found in order so far, in 0..3.  On return *have is updated to the new
1348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   state.  If on return *have equals four, then the pattern was found and the
1349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   return value is how many bytes were read including the last byte of the
1350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   pattern.  If *have is less than four, then the pattern has not been found
1351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   yet and the return value is len.  In the latter case, syncsearch() can be
1352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   called again with more data and the *have state.  *have is initialized to
1353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   zero for the first call.
1354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */
1355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovlocal unsigned syncsearch(
1356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovunsigned FAR *have,
1357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovconst unsigned char FAR *buf,
1358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovunsigned len)
1359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned got;
1361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned next;
1362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    got = *have;
1364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    next = 0;
1365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (next < len && got < 4) {
1366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
1367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            got++;
1368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else if (buf[next])
1369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            got = 0;
1370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        else
1371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            got = 4 - got;
1372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        next++;
1373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    *have = got;
1375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return next;
1376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflateSync(
1379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm)
1380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned len;               /* number of bytes to look at or looked at */
1382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned long in, out;      /* temporary to save total_in and total_out */
1383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned char buf[4];       /* to restore bit buffer to byte string */
1384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
1385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* check parameters */
1387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
1389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
1390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* if first time, start search in bit buffer */
1392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->mode != SYNC) {
1393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->mode = SYNC;
1394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->hold <<= state->bits & 7;
1395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->bits -= state->bits & 7;
1396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        len = 0;
1397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (state->bits >= 8) {
1398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            buf[len++] = (unsigned char)(state->hold);
1399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->hold >>= 8;
1400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            state->bits -= 8;
1401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->have = 0;
1403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        syncsearch(&(state->have), buf, len);
1404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* search available input */
1407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
1408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strm->avail_in -= len;
1409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strm->next_in += len;
1410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strm->total_in += len;
1411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* return no joy or set up to restart inflate() on a new block */
1413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->have != 4) return Z_DATA_ERROR;
1414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    in = strm->total_in;  out = strm->total_out;
1415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    inflateReset(strm);
1416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    strm->total_in = in;  strm->total_out = out;
1417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->mode = TYPE;
1418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return Z_OK;
1419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/*
1422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   Returns true if inflate is currently at the end of a block generated by
1423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
1424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   implementation to provide an additional safety check. PPP uses
1425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
1426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   block. When decompressing, PPP checks that at the end of input packet,
1427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov   inflate is waiting for these length bytes.
1428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */
1429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflateSyncPoint(
1430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm)
1431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
1433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
1436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return state->mode == STORED && state->bits == 0;
1437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflateCopy(
1440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp dest,
1441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp source)
1442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
1444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *copy;
1445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned char FAR *window;
1446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    unsigned wsize;
1447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* check input */
1449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
1450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
1451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return Z_STREAM_ERROR;
1452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)source->state;
1453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* allocate space */
1455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    copy = (struct inflate_state FAR *)
1456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov           ZALLOC(source, 1, sizeof(struct inflate_state));
1457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (copy == Z_NULL) return Z_MEM_ERROR;
1458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    window = Z_NULL;
1459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->window != Z_NULL) {
1460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        window = (unsigned char FAR *)
1461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
1462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (window == Z_NULL) {
1463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ZFREE(source, copy);
1464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return Z_MEM_ERROR;
1465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    /* copy state */
1469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
1470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
1471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (state->lencode >= state->codes &&
1472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        state->lencode <= state->codes + ENOUGH - 1) {
1473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        copy->lencode = copy->codes + (state->lencode - state->codes);
1474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        copy->distcode = copy->codes + (state->distcode - state->codes);
1475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    copy->next = copy->codes + (state->next - state->codes);
1477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (window != Z_NULL) {
1478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        wsize = 1U << state->wbits;
1479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        zmemcpy(window, state->window, wsize);
1480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    copy->window = window;
1482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    dest->state = (struct internal_state FAR *)copy;
1483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return Z_OK;
1484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint ZEXPORT inflateUndermine(
1487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm,
1488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint subvert)
1489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
1491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
1493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
1494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->sane = !subvert;
1495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
1496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return Z_OK;
1497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
1498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state->sane = 1;
1499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return Z_DATA_ERROR;
1500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovlong ZEXPORT inflateMark(
1504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovz_streamp strm)
1505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    struct inflate_state FAR *state;
1507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
1508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
1509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    state = (struct inflate_state FAR *)strm->state;
1510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ((long)(state->back) << 16) +
1511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        (state->mode == COPY ? state->length :
1512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            (state->mode == MATCH ? state->was - state->length : 0));
1513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1514