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