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