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