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