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