1*bbb1b6f9SApple OSS Distributions /*
2*bbb1b6f9SApple OSS Distributions * Copyright (c) 2008-2016 Apple Inc. All rights reserved.
3*bbb1b6f9SApple OSS Distributions *
4*bbb1b6f9SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5*bbb1b6f9SApple OSS Distributions *
6*bbb1b6f9SApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code
7*bbb1b6f9SApple OSS Distributions * as defined in and that are subject to the Apple Public Source License
8*bbb1b6f9SApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in
9*bbb1b6f9SApple OSS Distributions * compliance with the License. The rights granted to you under the License
10*bbb1b6f9SApple OSS Distributions * may not be used to create, or enable the creation or redistribution of,
11*bbb1b6f9SApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to
12*bbb1b6f9SApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any
13*bbb1b6f9SApple OSS Distributions * terms of an Apple operating system software license agreement.
14*bbb1b6f9SApple OSS Distributions *
15*bbb1b6f9SApple OSS Distributions * Please obtain a copy of the License at
16*bbb1b6f9SApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file.
17*bbb1b6f9SApple OSS Distributions *
18*bbb1b6f9SApple OSS Distributions * The Original Code and all software distributed under the License are
19*bbb1b6f9SApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20*bbb1b6f9SApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21*bbb1b6f9SApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22*bbb1b6f9SApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23*bbb1b6f9SApple OSS Distributions * Please see the License for the specific language governing rights and
24*bbb1b6f9SApple OSS Distributions * limitations under the License.
25*bbb1b6f9SApple OSS Distributions *
26*bbb1b6f9SApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27*bbb1b6f9SApple OSS Distributions */
28*bbb1b6f9SApple OSS Distributions /* infback.c -- inflate using a call-back interface
29*bbb1b6f9SApple OSS Distributions * Copyright (C) 1995-2005 Mark Adler
30*bbb1b6f9SApple OSS Distributions * For conditions of distribution and use, see copyright notice in zlib.h
31*bbb1b6f9SApple OSS Distributions */
32*bbb1b6f9SApple OSS Distributions
33*bbb1b6f9SApple OSS Distributions /*
34*bbb1b6f9SApple OSS Distributions This code is largely copied from inflate.c. Normally either infback.o or
35*bbb1b6f9SApple OSS Distributions inflate.o would be linked into an application--not both. The interface
36*bbb1b6f9SApple OSS Distributions with inffast.c is retained so that optimized assembler-coded versions of
37*bbb1b6f9SApple OSS Distributions inflate_fast() can be used with either inflate.c or infback.c.
38*bbb1b6f9SApple OSS Distributions */
39*bbb1b6f9SApple OSS Distributions
40*bbb1b6f9SApple OSS Distributions #include "zutil.h"
41*bbb1b6f9SApple OSS Distributions #include "inftrees.h"
42*bbb1b6f9SApple OSS Distributions #include "inflate.h"
43*bbb1b6f9SApple OSS Distributions #include "inffast.h"
44*bbb1b6f9SApple OSS Distributions #include <os/base.h>
45*bbb1b6f9SApple OSS Distributions
46*bbb1b6f9SApple OSS Distributions /* function prototypes */
47*bbb1b6f9SApple OSS Distributions local void fixedtables OF((struct inflate_state FAR *state));
48*bbb1b6f9SApple OSS Distributions
49*bbb1b6f9SApple OSS Distributions /*
50*bbb1b6f9SApple OSS Distributions strm provides memory allocation functions in zalloc and zfree, or
51*bbb1b6f9SApple OSS Distributions Z_NULL to use the library memory allocation functions.
52*bbb1b6f9SApple OSS Distributions
53*bbb1b6f9SApple OSS Distributions windowBits is in the range 8..15, and window is a user-supplied
54*bbb1b6f9SApple OSS Distributions window and output buffer that is 2**windowBits bytes.
55*bbb1b6f9SApple OSS Distributions */
56*bbb1b6f9SApple OSS Distributions int ZEXPORT
inflateBackInit_(z_streamp strm,int windowBits,unsigned char FAR * window,const char * version,int stream_size)57*bbb1b6f9SApple OSS Distributions inflateBackInit_(z_streamp strm, int windowBits, unsigned char FAR *window,
58*bbb1b6f9SApple OSS Distributions const char *version, int stream_size)
59*bbb1b6f9SApple OSS Distributions {
60*bbb1b6f9SApple OSS Distributions struct inflate_state FAR *state;
61*bbb1b6f9SApple OSS Distributions
62*bbb1b6f9SApple OSS Distributions if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
63*bbb1b6f9SApple OSS Distributions stream_size != (int)(sizeof(z_stream)))
64*bbb1b6f9SApple OSS Distributions return Z_VERSION_ERROR;
65*bbb1b6f9SApple OSS Distributions if (strm == Z_NULL || window == Z_NULL ||
66*bbb1b6f9SApple OSS Distributions windowBits < 8 || windowBits > 15)
67*bbb1b6f9SApple OSS Distributions return Z_STREAM_ERROR;
68*bbb1b6f9SApple OSS Distributions strm->msg = Z_NULL; /* in case we return an error */
69*bbb1b6f9SApple OSS Distributions #ifndef NO_ZCFUNCS
70*bbb1b6f9SApple OSS Distributions if (strm->zalloc == (alloc_func)0) {
71*bbb1b6f9SApple OSS Distributions strm->zalloc = zcalloc;
72*bbb1b6f9SApple OSS Distributions strm->opaque = (voidpf)0;
73*bbb1b6f9SApple OSS Distributions }
74*bbb1b6f9SApple OSS Distributions if (strm->zfree == (free_func)0) strm->zfree = zcfree;
75*bbb1b6f9SApple OSS Distributions #endif /* NO_ZCFUNCS */
76*bbb1b6f9SApple OSS Distributions state = (struct inflate_state FAR *)ZALLOC(strm, 1,
77*bbb1b6f9SApple OSS Distributions sizeof(struct inflate_state));
78*bbb1b6f9SApple OSS Distributions if (state == Z_NULL) return Z_MEM_ERROR;
79*bbb1b6f9SApple OSS Distributions Tracev((stderr, "inflate: allocated\n"));
80*bbb1b6f9SApple OSS Distributions strm->state = (struct internal_state FAR *)state;
81*bbb1b6f9SApple OSS Distributions state->dmax = 32768U;
82*bbb1b6f9SApple OSS Distributions state->wbits = windowBits;
83*bbb1b6f9SApple OSS Distributions state->wsize = 1U << windowBits;
84*bbb1b6f9SApple OSS Distributions state->window = window;
85*bbb1b6f9SApple OSS Distributions state->write = 0;
86*bbb1b6f9SApple OSS Distributions state->whave = 0;
87*bbb1b6f9SApple OSS Distributions return Z_OK;
88*bbb1b6f9SApple OSS Distributions }
89*bbb1b6f9SApple OSS Distributions
90*bbb1b6f9SApple OSS Distributions /*
91*bbb1b6f9SApple OSS Distributions Return state with length and distance decoding tables and index sizes set to
92*bbb1b6f9SApple OSS Distributions fixed code decoding. Normally this returns fixed tables from inffixed.h.
93*bbb1b6f9SApple OSS Distributions If BUILDFIXED is defined, then instead this routine builds the tables the
94*bbb1b6f9SApple OSS Distributions first time it's called, and returns those tables the first time and
95*bbb1b6f9SApple OSS Distributions thereafter. This reduces the size of the code by about 2K bytes, in
96*bbb1b6f9SApple OSS Distributions exchange for a little execution time. However, BUILDFIXED should not be
97*bbb1b6f9SApple OSS Distributions used for threaded applications, since the rewriting of the tables and virgin
98*bbb1b6f9SApple OSS Distributions may not be thread-safe.
99*bbb1b6f9SApple OSS Distributions */
100*bbb1b6f9SApple OSS Distributions local void
fixedtables(struct inflate_state FAR * state)101*bbb1b6f9SApple OSS Distributions fixedtables(struct inflate_state FAR *state)
102*bbb1b6f9SApple OSS Distributions {
103*bbb1b6f9SApple OSS Distributions #ifdef BUILDFIXED
104*bbb1b6f9SApple OSS Distributions static int virgin = 1;
105*bbb1b6f9SApple OSS Distributions static code *lenfix, *distfix;
106*bbb1b6f9SApple OSS Distributions static code fixed[544];
107*bbb1b6f9SApple OSS Distributions
108*bbb1b6f9SApple OSS Distributions /* build fixed huffman tables if first call (may not be thread safe) */
109*bbb1b6f9SApple OSS Distributions if (virgin) {
110*bbb1b6f9SApple OSS Distributions unsigned sym, bits;
111*bbb1b6f9SApple OSS Distributions static code *next;
112*bbb1b6f9SApple OSS Distributions
113*bbb1b6f9SApple OSS Distributions /* literal/length table */
114*bbb1b6f9SApple OSS Distributions sym = 0;
115*bbb1b6f9SApple OSS Distributions while (sym < 144) state->lens[sym++] = 8;
116*bbb1b6f9SApple OSS Distributions while (sym < 256) state->lens[sym++] = 9;
117*bbb1b6f9SApple OSS Distributions while (sym < 280) state->lens[sym++] = 7;
118*bbb1b6f9SApple OSS Distributions while (sym < 288) state->lens[sym++] = 8;
119*bbb1b6f9SApple OSS Distributions next = fixed;
120*bbb1b6f9SApple OSS Distributions lenfix = next;
121*bbb1b6f9SApple OSS Distributions bits = 9;
122*bbb1b6f9SApple OSS Distributions inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
123*bbb1b6f9SApple OSS Distributions
124*bbb1b6f9SApple OSS Distributions /* distance table */
125*bbb1b6f9SApple OSS Distributions sym = 0;
126*bbb1b6f9SApple OSS Distributions while (sym < 32) state->lens[sym++] = 5;
127*bbb1b6f9SApple OSS Distributions distfix = next;
128*bbb1b6f9SApple OSS Distributions bits = 5;
129*bbb1b6f9SApple OSS Distributions inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
130*bbb1b6f9SApple OSS Distributions
131*bbb1b6f9SApple OSS Distributions /* do this just once */
132*bbb1b6f9SApple OSS Distributions virgin = 0;
133*bbb1b6f9SApple OSS Distributions }
134*bbb1b6f9SApple OSS Distributions #else /* !BUILDFIXED */
135*bbb1b6f9SApple OSS Distributions # include "inffixed.h"
136*bbb1b6f9SApple OSS Distributions #endif /* BUILDFIXED */
137*bbb1b6f9SApple OSS Distributions state->lencode = lenfix;
138*bbb1b6f9SApple OSS Distributions state->lenbits = 9;
139*bbb1b6f9SApple OSS Distributions state->distcode = distfix;
140*bbb1b6f9SApple OSS Distributions state->distbits = 5;
141*bbb1b6f9SApple OSS Distributions }
142*bbb1b6f9SApple OSS Distributions
143*bbb1b6f9SApple OSS Distributions /* Macros for inflateBack(): */
144*bbb1b6f9SApple OSS Distributions
145*bbb1b6f9SApple OSS Distributions /* Load returned state from inflate_fast() */
146*bbb1b6f9SApple OSS Distributions #define LOAD() \
147*bbb1b6f9SApple OSS Distributions do { \
148*bbb1b6f9SApple OSS Distributions put = strm->next_out; \
149*bbb1b6f9SApple OSS Distributions left = strm->avail_out; \
150*bbb1b6f9SApple OSS Distributions next = strm->next_in; \
151*bbb1b6f9SApple OSS Distributions have = strm->avail_in; \
152*bbb1b6f9SApple OSS Distributions hold = state->hold; \
153*bbb1b6f9SApple OSS Distributions bits = state->bits; \
154*bbb1b6f9SApple OSS Distributions } while (0)
155*bbb1b6f9SApple OSS Distributions
156*bbb1b6f9SApple OSS Distributions /* Set state from registers for inflate_fast() */
157*bbb1b6f9SApple OSS Distributions #define RESTORE() \
158*bbb1b6f9SApple OSS Distributions do { \
159*bbb1b6f9SApple OSS Distributions strm->next_out = put; \
160*bbb1b6f9SApple OSS Distributions strm->avail_out = left; \
161*bbb1b6f9SApple OSS Distributions strm->next_in = next; \
162*bbb1b6f9SApple OSS Distributions strm->avail_in = have; \
163*bbb1b6f9SApple OSS Distributions state->hold = hold; \
164*bbb1b6f9SApple OSS Distributions state->bits = bits; \
165*bbb1b6f9SApple OSS Distributions } while (0)
166*bbb1b6f9SApple OSS Distributions
167*bbb1b6f9SApple OSS Distributions /* Clear the input bit accumulator */
168*bbb1b6f9SApple OSS Distributions #define INITBITS() \
169*bbb1b6f9SApple OSS Distributions do { \
170*bbb1b6f9SApple OSS Distributions hold = 0; \
171*bbb1b6f9SApple OSS Distributions bits = 0; \
172*bbb1b6f9SApple OSS Distributions } while (0)
173*bbb1b6f9SApple OSS Distributions
174*bbb1b6f9SApple OSS Distributions /* Assure that some input is available. If input is requested, but denied,
175*bbb1b6f9SApple OSS Distributions then return a Z_BUF_ERROR from inflateBack(). */
176*bbb1b6f9SApple OSS Distributions #define PULL() \
177*bbb1b6f9SApple OSS Distributions do { \
178*bbb1b6f9SApple OSS Distributions if (have == 0) { \
179*bbb1b6f9SApple OSS Distributions have = in(in_desc, &next); \
180*bbb1b6f9SApple OSS Distributions if (have == 0) { \
181*bbb1b6f9SApple OSS Distributions next = Z_NULL; \
182*bbb1b6f9SApple OSS Distributions ret = Z_BUF_ERROR; \
183*bbb1b6f9SApple OSS Distributions goto inf_leave; \
184*bbb1b6f9SApple OSS Distributions } \
185*bbb1b6f9SApple OSS Distributions } \
186*bbb1b6f9SApple OSS Distributions } while (0)
187*bbb1b6f9SApple OSS Distributions
188*bbb1b6f9SApple OSS Distributions /* Get a byte of input into the bit accumulator, or return from inflateBack()
189*bbb1b6f9SApple OSS Distributions with an error if there is no input available. */
190*bbb1b6f9SApple OSS Distributions #define PULLBYTE() \
191*bbb1b6f9SApple OSS Distributions do { \
192*bbb1b6f9SApple OSS Distributions PULL(); \
193*bbb1b6f9SApple OSS Distributions have--; \
194*bbb1b6f9SApple OSS Distributions hold += (unsigned long)(*next++) << bits; \
195*bbb1b6f9SApple OSS Distributions bits += 8; \
196*bbb1b6f9SApple OSS Distributions } while (0)
197*bbb1b6f9SApple OSS Distributions
198*bbb1b6f9SApple OSS Distributions /* Assure that there are at least n bits in the bit accumulator. If there is
199*bbb1b6f9SApple OSS Distributions not enough available input to do that, then return from inflateBack() with
200*bbb1b6f9SApple OSS Distributions an error. */
201*bbb1b6f9SApple OSS Distributions #define NEEDBITS(n) \
202*bbb1b6f9SApple OSS Distributions do { \
203*bbb1b6f9SApple OSS Distributions while (bits < (unsigned)(n)) \
204*bbb1b6f9SApple OSS Distributions PULLBYTE(); \
205*bbb1b6f9SApple OSS Distributions } while (0)
206*bbb1b6f9SApple OSS Distributions
207*bbb1b6f9SApple OSS Distributions /* Return the low n bits of the bit accumulator (n < 16) */
208*bbb1b6f9SApple OSS Distributions #define BITS(n) \
209*bbb1b6f9SApple OSS Distributions ((unsigned)hold & ((1U << (n)) - 1))
210*bbb1b6f9SApple OSS Distributions
211*bbb1b6f9SApple OSS Distributions /* Remove n bits from the bit accumulator */
212*bbb1b6f9SApple OSS Distributions #define DROPBITS(n) \
213*bbb1b6f9SApple OSS Distributions do { \
214*bbb1b6f9SApple OSS Distributions hold >>= (n); \
215*bbb1b6f9SApple OSS Distributions bits -= (unsigned)(n); \
216*bbb1b6f9SApple OSS Distributions } while (0)
217*bbb1b6f9SApple OSS Distributions
218*bbb1b6f9SApple OSS Distributions /* Remove zero to seven bits as needed to go to a byte boundary */
219*bbb1b6f9SApple OSS Distributions #define BYTEBITS() \
220*bbb1b6f9SApple OSS Distributions do { \
221*bbb1b6f9SApple OSS Distributions hold >>= bits & 7; \
222*bbb1b6f9SApple OSS Distributions bits -= bits & 7; \
223*bbb1b6f9SApple OSS Distributions } while (0)
224*bbb1b6f9SApple OSS Distributions
225*bbb1b6f9SApple OSS Distributions /* Assure that some output space is available, by writing out the window
226*bbb1b6f9SApple OSS Distributions if it's full. If the write fails, return from inflateBack() with a
227*bbb1b6f9SApple OSS Distributions Z_BUF_ERROR. */
228*bbb1b6f9SApple OSS Distributions #define ROOM() \
229*bbb1b6f9SApple OSS Distributions do { \
230*bbb1b6f9SApple OSS Distributions if (left == 0) { \
231*bbb1b6f9SApple OSS Distributions put = state->window; \
232*bbb1b6f9SApple OSS Distributions left = state->wsize; \
233*bbb1b6f9SApple OSS Distributions state->whave = left; \
234*bbb1b6f9SApple OSS Distributions if (out(out_desc, put, left)) { \
235*bbb1b6f9SApple OSS Distributions ret = Z_BUF_ERROR; \
236*bbb1b6f9SApple OSS Distributions goto inf_leave; \
237*bbb1b6f9SApple OSS Distributions } \
238*bbb1b6f9SApple OSS Distributions } \
239*bbb1b6f9SApple OSS Distributions } while (0)
240*bbb1b6f9SApple OSS Distributions
241*bbb1b6f9SApple OSS Distributions /*
242*bbb1b6f9SApple OSS Distributions strm provides the memory allocation functions and window buffer on input,
243*bbb1b6f9SApple OSS Distributions and provides information on the unused input on return. For Z_DATA_ERROR
244*bbb1b6f9SApple OSS Distributions returns, strm will also provide an error message.
245*bbb1b6f9SApple OSS Distributions
246*bbb1b6f9SApple OSS Distributions in() and out() are the call-back input and output functions. When
247*bbb1b6f9SApple OSS Distributions inflateBack() needs more input, it calls in(). When inflateBack() has
248*bbb1b6f9SApple OSS Distributions filled the window with output, or when it completes with data in the
249*bbb1b6f9SApple OSS Distributions window, it calls out() to write out the data. The application must not
250*bbb1b6f9SApple OSS Distributions change the provided input until in() is called again or inflateBack()
251*bbb1b6f9SApple OSS Distributions returns. The application must not change the window/output buffer until
252*bbb1b6f9SApple OSS Distributions inflateBack() returns.
253*bbb1b6f9SApple OSS Distributions
254*bbb1b6f9SApple OSS Distributions in() and out() are called with a descriptor parameter provided in the
255*bbb1b6f9SApple OSS Distributions inflateBack() call. This parameter can be a structure that provides the
256*bbb1b6f9SApple OSS Distributions information required to do the read or write, as well as accumulated
257*bbb1b6f9SApple OSS Distributions information on the input and output such as totals and check values.
258*bbb1b6f9SApple OSS Distributions
259*bbb1b6f9SApple OSS Distributions in() should return zero on failure. out() should return non-zero on
260*bbb1b6f9SApple OSS Distributions failure. If either in() or out() fails, than inflateBack() returns a
261*bbb1b6f9SApple OSS Distributions Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
262*bbb1b6f9SApple OSS Distributions was in() or out() that caused in the error. Otherwise, inflateBack()
263*bbb1b6f9SApple OSS Distributions returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
264*bbb1b6f9SApple OSS Distributions error, or Z_MEM_ERROR if it could not allocate memory for the state.
265*bbb1b6f9SApple OSS Distributions inflateBack() can also return Z_STREAM_ERROR if the input parameters
266*bbb1b6f9SApple OSS Distributions are not correct, i.e. strm is Z_NULL or the state was not initialized.
267*bbb1b6f9SApple OSS Distributions */
268*bbb1b6f9SApple OSS Distributions int ZEXPORT
inflateBack(z_streamp strm,in_func in,void FAR * in_desc,out_func out,void FAR * out_desc)269*bbb1b6f9SApple OSS Distributions inflateBack(z_streamp strm, in_func in, void FAR *in_desc, out_func out,
270*bbb1b6f9SApple OSS Distributions void FAR *out_desc)
271*bbb1b6f9SApple OSS Distributions {
272*bbb1b6f9SApple OSS Distributions struct inflate_state FAR *state;
273*bbb1b6f9SApple OSS Distributions unsigned char FAR *next; /* next input */
274*bbb1b6f9SApple OSS Distributions unsigned char FAR *put; /* next output */
275*bbb1b6f9SApple OSS Distributions unsigned have, left; /* available input and output */
276*bbb1b6f9SApple OSS Distributions unsigned long hold; /* bit buffer */
277*bbb1b6f9SApple OSS Distributions unsigned bits; /* bits in bit buffer */
278*bbb1b6f9SApple OSS Distributions unsigned copy; /* number of stored or match bytes to copy */
279*bbb1b6f9SApple OSS Distributions unsigned char FAR *from; /* where to copy match bytes from */
280*bbb1b6f9SApple OSS Distributions code this; /* current decoding table entry */
281*bbb1b6f9SApple OSS Distributions code last; /* parent table entry */
282*bbb1b6f9SApple OSS Distributions unsigned len; /* length to copy for repeats, bits to drop */
283*bbb1b6f9SApple OSS Distributions int ret; /* return code */
284*bbb1b6f9SApple OSS Distributions static const unsigned short order[19] = /* permutation of code lengths */
285*bbb1b6f9SApple OSS Distributions {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
286*bbb1b6f9SApple OSS Distributions
287*bbb1b6f9SApple OSS Distributions /* Check that the strm exists and that the state was initialized */
288*bbb1b6f9SApple OSS Distributions if (strm == Z_NULL || strm->state == Z_NULL)
289*bbb1b6f9SApple OSS Distributions return Z_STREAM_ERROR;
290*bbb1b6f9SApple OSS Distributions state = (struct inflate_state FAR *)strm->state;
291*bbb1b6f9SApple OSS Distributions
292*bbb1b6f9SApple OSS Distributions /* Reset the state */
293*bbb1b6f9SApple OSS Distributions strm->msg = Z_NULL;
294*bbb1b6f9SApple OSS Distributions state->mode = TYPE;
295*bbb1b6f9SApple OSS Distributions state->last = 0;
296*bbb1b6f9SApple OSS Distributions state->whave = 0;
297*bbb1b6f9SApple OSS Distributions next = strm->next_in;
298*bbb1b6f9SApple OSS Distributions have = next != Z_NULL ? strm->avail_in : 0;
299*bbb1b6f9SApple OSS Distributions hold = 0;
300*bbb1b6f9SApple OSS Distributions bits = 0;
301*bbb1b6f9SApple OSS Distributions put = state->window;
302*bbb1b6f9SApple OSS Distributions left = state->wsize;
303*bbb1b6f9SApple OSS Distributions
304*bbb1b6f9SApple OSS Distributions /* Inflate until end of block marked as last */
305*bbb1b6f9SApple OSS Distributions for (;;)
306*bbb1b6f9SApple OSS Distributions switch (state->mode) {
307*bbb1b6f9SApple OSS Distributions case TYPE:
308*bbb1b6f9SApple OSS Distributions /* determine and dispatch block type */
309*bbb1b6f9SApple OSS Distributions if (state->last) {
310*bbb1b6f9SApple OSS Distributions BYTEBITS();
311*bbb1b6f9SApple OSS Distributions state->mode = DONE;
312*bbb1b6f9SApple OSS Distributions break;
313*bbb1b6f9SApple OSS Distributions }
314*bbb1b6f9SApple OSS Distributions NEEDBITS(3);
315*bbb1b6f9SApple OSS Distributions state->last = BITS(1);
316*bbb1b6f9SApple OSS Distributions DROPBITS(1);
317*bbb1b6f9SApple OSS Distributions switch (BITS(2)) {
318*bbb1b6f9SApple OSS Distributions case 0: /* stored block */
319*bbb1b6f9SApple OSS Distributions Tracev((stderr, "inflate: stored block%s\n",
320*bbb1b6f9SApple OSS Distributions state->last ? " (last)" : ""));
321*bbb1b6f9SApple OSS Distributions state->mode = STORED;
322*bbb1b6f9SApple OSS Distributions break;
323*bbb1b6f9SApple OSS Distributions case 1: /* fixed block */
324*bbb1b6f9SApple OSS Distributions fixedtables(state);
325*bbb1b6f9SApple OSS Distributions Tracev((stderr, "inflate: fixed codes block%s\n",
326*bbb1b6f9SApple OSS Distributions state->last ? " (last)" : ""));
327*bbb1b6f9SApple OSS Distributions state->mode = LEN; /* decode codes */
328*bbb1b6f9SApple OSS Distributions break;
329*bbb1b6f9SApple OSS Distributions case 2: /* dynamic block */
330*bbb1b6f9SApple OSS Distributions Tracev((stderr, "inflate: dynamic codes block%s\n",
331*bbb1b6f9SApple OSS Distributions state->last ? " (last)" : ""));
332*bbb1b6f9SApple OSS Distributions state->mode = TABLE;
333*bbb1b6f9SApple OSS Distributions break;
334*bbb1b6f9SApple OSS Distributions case 3:
335*bbb1b6f9SApple OSS Distributions strm->msg = (char *)"invalid block type";
336*bbb1b6f9SApple OSS Distributions state->mode = BAD;
337*bbb1b6f9SApple OSS Distributions }
338*bbb1b6f9SApple OSS Distributions DROPBITS(2);
339*bbb1b6f9SApple OSS Distributions break;
340*bbb1b6f9SApple OSS Distributions
341*bbb1b6f9SApple OSS Distributions case STORED:
342*bbb1b6f9SApple OSS Distributions /* get and verify stored block length */
343*bbb1b6f9SApple OSS Distributions BYTEBITS(); /* go to byte boundary */
344*bbb1b6f9SApple OSS Distributions NEEDBITS(32);
345*bbb1b6f9SApple OSS Distributions if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
346*bbb1b6f9SApple OSS Distributions strm->msg = (char *)"invalid stored block lengths";
347*bbb1b6f9SApple OSS Distributions state->mode = BAD;
348*bbb1b6f9SApple OSS Distributions break;
349*bbb1b6f9SApple OSS Distributions }
350*bbb1b6f9SApple OSS Distributions state->length = (unsigned)hold & 0xffff;
351*bbb1b6f9SApple OSS Distributions Tracev((stderr, "inflate: stored length %u\n",
352*bbb1b6f9SApple OSS Distributions state->length));
353*bbb1b6f9SApple OSS Distributions INITBITS();
354*bbb1b6f9SApple OSS Distributions
355*bbb1b6f9SApple OSS Distributions /* copy stored block from input to output */
356*bbb1b6f9SApple OSS Distributions while (state->length != 0) {
357*bbb1b6f9SApple OSS Distributions copy = state->length;
358*bbb1b6f9SApple OSS Distributions PULL();
359*bbb1b6f9SApple OSS Distributions ROOM();
360*bbb1b6f9SApple OSS Distributions if (copy > have) copy = have;
361*bbb1b6f9SApple OSS Distributions if (copy > left) copy = left;
362*bbb1b6f9SApple OSS Distributions zmemcpy(put, next, copy);
363*bbb1b6f9SApple OSS Distributions have -= copy;
364*bbb1b6f9SApple OSS Distributions next += copy;
365*bbb1b6f9SApple OSS Distributions left -= copy;
366*bbb1b6f9SApple OSS Distributions put += copy;
367*bbb1b6f9SApple OSS Distributions state->length -= copy;
368*bbb1b6f9SApple OSS Distributions }
369*bbb1b6f9SApple OSS Distributions Tracev((stderr, "inflate: stored end\n"));
370*bbb1b6f9SApple OSS Distributions state->mode = TYPE;
371*bbb1b6f9SApple OSS Distributions break;
372*bbb1b6f9SApple OSS Distributions
373*bbb1b6f9SApple OSS Distributions case TABLE:
374*bbb1b6f9SApple OSS Distributions /* get dynamic table entries descriptor */
375*bbb1b6f9SApple OSS Distributions NEEDBITS(14);
376*bbb1b6f9SApple OSS Distributions state->nlen = BITS(5) + 257;
377*bbb1b6f9SApple OSS Distributions DROPBITS(5);
378*bbb1b6f9SApple OSS Distributions state->ndist = BITS(5) + 1;
379*bbb1b6f9SApple OSS Distributions DROPBITS(5);
380*bbb1b6f9SApple OSS Distributions state->ncode = BITS(4) + 4;
381*bbb1b6f9SApple OSS Distributions DROPBITS(4);
382*bbb1b6f9SApple OSS Distributions #ifndef PKZIP_BUG_WORKAROUND
383*bbb1b6f9SApple OSS Distributions if (state->nlen > 286 || state->ndist > 30) {
384*bbb1b6f9SApple OSS Distributions strm->msg = (char *)"too many length or distance symbols";
385*bbb1b6f9SApple OSS Distributions state->mode = BAD;
386*bbb1b6f9SApple OSS Distributions break;
387*bbb1b6f9SApple OSS Distributions }
388*bbb1b6f9SApple OSS Distributions #endif
389*bbb1b6f9SApple OSS Distributions Tracev((stderr, "inflate: table sizes ok\n"));
390*bbb1b6f9SApple OSS Distributions
391*bbb1b6f9SApple OSS Distributions /* get code length code lengths (not a typo) */
392*bbb1b6f9SApple OSS Distributions state->have = 0;
393*bbb1b6f9SApple OSS Distributions while (state->have < state->ncode) {
394*bbb1b6f9SApple OSS Distributions NEEDBITS(3);
395*bbb1b6f9SApple OSS Distributions state->lens[order[state->have++]] = (unsigned short)BITS(3);
396*bbb1b6f9SApple OSS Distributions DROPBITS(3);
397*bbb1b6f9SApple OSS Distributions }
398*bbb1b6f9SApple OSS Distributions while (state->have < 19)
399*bbb1b6f9SApple OSS Distributions state->lens[order[state->have++]] = 0;
400*bbb1b6f9SApple OSS Distributions state->next = state->codes;
401*bbb1b6f9SApple OSS Distributions state->lencode = (code const FAR *)(state->next);
402*bbb1b6f9SApple OSS Distributions state->lenbits = 7;
403*bbb1b6f9SApple OSS Distributions ret = inflate_table(CODES, state->lens, 19, &(state->next),
404*bbb1b6f9SApple OSS Distributions &(state->lenbits), state->work);
405*bbb1b6f9SApple OSS Distributions if (ret) {
406*bbb1b6f9SApple OSS Distributions strm->msg = (char *)"invalid code lengths set";
407*bbb1b6f9SApple OSS Distributions state->mode = BAD;
408*bbb1b6f9SApple OSS Distributions break;
409*bbb1b6f9SApple OSS Distributions }
410*bbb1b6f9SApple OSS Distributions Tracev((stderr, "inflate: code lengths ok\n"));
411*bbb1b6f9SApple OSS Distributions
412*bbb1b6f9SApple OSS Distributions /* get length and distance code code lengths */
413*bbb1b6f9SApple OSS Distributions state->have = 0;
414*bbb1b6f9SApple OSS Distributions while (state->have < state->nlen + state->ndist) {
415*bbb1b6f9SApple OSS Distributions for (;;) {
416*bbb1b6f9SApple OSS Distributions this = state->lencode[BITS(state->lenbits)];
417*bbb1b6f9SApple OSS Distributions if ((unsigned)(this.bits) <= bits) break;
418*bbb1b6f9SApple OSS Distributions PULLBYTE();
419*bbb1b6f9SApple OSS Distributions }
420*bbb1b6f9SApple OSS Distributions if (this.val < 16) {
421*bbb1b6f9SApple OSS Distributions NEEDBITS(this.bits);
422*bbb1b6f9SApple OSS Distributions DROPBITS(this.bits);
423*bbb1b6f9SApple OSS Distributions state->lens[state->have++] = this.val;
424*bbb1b6f9SApple OSS Distributions }
425*bbb1b6f9SApple OSS Distributions else {
426*bbb1b6f9SApple OSS Distributions if (this.val == 16) {
427*bbb1b6f9SApple OSS Distributions NEEDBITS(this.bits + 2);
428*bbb1b6f9SApple OSS Distributions DROPBITS(this.bits);
429*bbb1b6f9SApple OSS Distributions if (state->have == 0) {
430*bbb1b6f9SApple OSS Distributions strm->msg = (char *)"invalid bit length repeat";
431*bbb1b6f9SApple OSS Distributions state->mode = BAD;
432*bbb1b6f9SApple OSS Distributions break;
433*bbb1b6f9SApple OSS Distributions }
434*bbb1b6f9SApple OSS Distributions len = (unsigned)(state->lens[state->have - 1]);
435*bbb1b6f9SApple OSS Distributions copy = 3 + BITS(2);
436*bbb1b6f9SApple OSS Distributions DROPBITS(2);
437*bbb1b6f9SApple OSS Distributions }
438*bbb1b6f9SApple OSS Distributions else if (this.val == 17) {
439*bbb1b6f9SApple OSS Distributions NEEDBITS(this.bits + 3);
440*bbb1b6f9SApple OSS Distributions DROPBITS(this.bits);
441*bbb1b6f9SApple OSS Distributions len = 0;
442*bbb1b6f9SApple OSS Distributions copy = 3 + BITS(3);
443*bbb1b6f9SApple OSS Distributions DROPBITS(3);
444*bbb1b6f9SApple OSS Distributions }
445*bbb1b6f9SApple OSS Distributions else {
446*bbb1b6f9SApple OSS Distributions NEEDBITS(this.bits + 7);
447*bbb1b6f9SApple OSS Distributions DROPBITS(this.bits);
448*bbb1b6f9SApple OSS Distributions len = 0;
449*bbb1b6f9SApple OSS Distributions copy = 11 + BITS(7);
450*bbb1b6f9SApple OSS Distributions DROPBITS(7);
451*bbb1b6f9SApple OSS Distributions }
452*bbb1b6f9SApple OSS Distributions if (state->have + copy > state->nlen + state->ndist) {
453*bbb1b6f9SApple OSS Distributions strm->msg = (char *)"invalid bit length repeat";
454*bbb1b6f9SApple OSS Distributions state->mode = BAD;
455*bbb1b6f9SApple OSS Distributions break;
456*bbb1b6f9SApple OSS Distributions }
457*bbb1b6f9SApple OSS Distributions while (copy--)
458*bbb1b6f9SApple OSS Distributions state->lens[state->have++] = (unsigned short)len;
459*bbb1b6f9SApple OSS Distributions }
460*bbb1b6f9SApple OSS Distributions }
461*bbb1b6f9SApple OSS Distributions
462*bbb1b6f9SApple OSS Distributions /* handle error breaks in while */
463*bbb1b6f9SApple OSS Distributions if (state->mode == BAD) break;
464*bbb1b6f9SApple OSS Distributions
465*bbb1b6f9SApple OSS Distributions /* build code tables */
466*bbb1b6f9SApple OSS Distributions state->next = state->codes;
467*bbb1b6f9SApple OSS Distributions state->lencode = (code const FAR *)(state->next);
468*bbb1b6f9SApple OSS Distributions state->lenbits = 9;
469*bbb1b6f9SApple OSS Distributions ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
470*bbb1b6f9SApple OSS Distributions &(state->lenbits), state->work);
471*bbb1b6f9SApple OSS Distributions if (ret) {
472*bbb1b6f9SApple OSS Distributions strm->msg = (char *)"invalid literal/lengths set";
473*bbb1b6f9SApple OSS Distributions state->mode = BAD;
474*bbb1b6f9SApple OSS Distributions break;
475*bbb1b6f9SApple OSS Distributions }
476*bbb1b6f9SApple OSS Distributions state->distcode = (code const FAR *)(state->next);
477*bbb1b6f9SApple OSS Distributions state->distbits = 6;
478*bbb1b6f9SApple OSS Distributions ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
479*bbb1b6f9SApple OSS Distributions &(state->next), &(state->distbits), state->work);
480*bbb1b6f9SApple OSS Distributions if (ret) {
481*bbb1b6f9SApple OSS Distributions strm->msg = (char *)"invalid distances set";
482*bbb1b6f9SApple OSS Distributions state->mode = BAD;
483*bbb1b6f9SApple OSS Distributions break;
484*bbb1b6f9SApple OSS Distributions }
485*bbb1b6f9SApple OSS Distributions Tracev((stderr, "inflate: codes ok\n"));
486*bbb1b6f9SApple OSS Distributions state->mode = LEN;
487*bbb1b6f9SApple OSS Distributions
488*bbb1b6f9SApple OSS Distributions OS_FALLTHROUGH;
489*bbb1b6f9SApple OSS Distributions case LEN:
490*bbb1b6f9SApple OSS Distributions /* use inflate_fast() if we have enough input and output */
491*bbb1b6f9SApple OSS Distributions if (have >= 6 && left >= 258) {
492*bbb1b6f9SApple OSS Distributions RESTORE();
493*bbb1b6f9SApple OSS Distributions if (state->whave < state->wsize)
494*bbb1b6f9SApple OSS Distributions state->whave = state->wsize - left;
495*bbb1b6f9SApple OSS Distributions inflate_fast(strm, state->wsize);
496*bbb1b6f9SApple OSS Distributions LOAD();
497*bbb1b6f9SApple OSS Distributions break;
498*bbb1b6f9SApple OSS Distributions }
499*bbb1b6f9SApple OSS Distributions
500*bbb1b6f9SApple OSS Distributions /* get a literal, length, or end-of-block code */
501*bbb1b6f9SApple OSS Distributions for (;;) {
502*bbb1b6f9SApple OSS Distributions this = state->lencode[BITS(state->lenbits)];
503*bbb1b6f9SApple OSS Distributions if ((unsigned)(this.bits) <= bits) break;
504*bbb1b6f9SApple OSS Distributions PULLBYTE();
505*bbb1b6f9SApple OSS Distributions }
506*bbb1b6f9SApple OSS Distributions if (this.op && (this.op & 0xf0) == 0) {
507*bbb1b6f9SApple OSS Distributions last = this;
508*bbb1b6f9SApple OSS Distributions for (;;) {
509*bbb1b6f9SApple OSS Distributions this = state->lencode[last.val +
510*bbb1b6f9SApple OSS Distributions (BITS(last.bits + last.op) >> last.bits)];
511*bbb1b6f9SApple OSS Distributions if ((unsigned)(last.bits + this.bits) <= bits) break;
512*bbb1b6f9SApple OSS Distributions PULLBYTE();
513*bbb1b6f9SApple OSS Distributions }
514*bbb1b6f9SApple OSS Distributions DROPBITS(last.bits);
515*bbb1b6f9SApple OSS Distributions }
516*bbb1b6f9SApple OSS Distributions DROPBITS(this.bits);
517*bbb1b6f9SApple OSS Distributions state->length = (unsigned)this.val;
518*bbb1b6f9SApple OSS Distributions
519*bbb1b6f9SApple OSS Distributions /* process literal */
520*bbb1b6f9SApple OSS Distributions if (this.op == 0) {
521*bbb1b6f9SApple OSS Distributions Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
522*bbb1b6f9SApple OSS Distributions "inflate: literal '%c'\n" :
523*bbb1b6f9SApple OSS Distributions "inflate: literal 0x%02x\n", this.val));
524*bbb1b6f9SApple OSS Distributions ROOM();
525*bbb1b6f9SApple OSS Distributions *put++ = (unsigned char)(state->length);
526*bbb1b6f9SApple OSS Distributions left--;
527*bbb1b6f9SApple OSS Distributions state->mode = LEN;
528*bbb1b6f9SApple OSS Distributions break;
529*bbb1b6f9SApple OSS Distributions }
530*bbb1b6f9SApple OSS Distributions
531*bbb1b6f9SApple OSS Distributions /* process end of block */
532*bbb1b6f9SApple OSS Distributions if (this.op & 32) {
533*bbb1b6f9SApple OSS Distributions Tracevv((stderr, "inflate: end of block\n"));
534*bbb1b6f9SApple OSS Distributions state->mode = TYPE;
535*bbb1b6f9SApple OSS Distributions break;
536*bbb1b6f9SApple OSS Distributions }
537*bbb1b6f9SApple OSS Distributions
538*bbb1b6f9SApple OSS Distributions /* invalid code */
539*bbb1b6f9SApple OSS Distributions if (this.op & 64) {
540*bbb1b6f9SApple OSS Distributions strm->msg = (char *)"invalid literal/length code";
541*bbb1b6f9SApple OSS Distributions state->mode = BAD;
542*bbb1b6f9SApple OSS Distributions break;
543*bbb1b6f9SApple OSS Distributions }
544*bbb1b6f9SApple OSS Distributions
545*bbb1b6f9SApple OSS Distributions /* length code -- get extra bits, if any */
546*bbb1b6f9SApple OSS Distributions state->extra = (unsigned)(this.op) & 15;
547*bbb1b6f9SApple OSS Distributions if (state->extra != 0) {
548*bbb1b6f9SApple OSS Distributions NEEDBITS(state->extra);
549*bbb1b6f9SApple OSS Distributions state->length += BITS(state->extra);
550*bbb1b6f9SApple OSS Distributions DROPBITS(state->extra);
551*bbb1b6f9SApple OSS Distributions }
552*bbb1b6f9SApple OSS Distributions Tracevv((stderr, "inflate: length %u\n", state->length));
553*bbb1b6f9SApple OSS Distributions
554*bbb1b6f9SApple OSS Distributions /* get distance code */
555*bbb1b6f9SApple OSS Distributions for (;;) {
556*bbb1b6f9SApple OSS Distributions this = state->distcode[BITS(state->distbits)];
557*bbb1b6f9SApple OSS Distributions if ((unsigned)(this.bits) <= bits) break;
558*bbb1b6f9SApple OSS Distributions PULLBYTE();
559*bbb1b6f9SApple OSS Distributions }
560*bbb1b6f9SApple OSS Distributions if ((this.op & 0xf0) == 0) {
561*bbb1b6f9SApple OSS Distributions last = this;
562*bbb1b6f9SApple OSS Distributions for (;;) {
563*bbb1b6f9SApple OSS Distributions this = state->distcode[last.val +
564*bbb1b6f9SApple OSS Distributions (BITS(last.bits + last.op) >> last.bits)];
565*bbb1b6f9SApple OSS Distributions if ((unsigned)(last.bits + this.bits) <= bits) break;
566*bbb1b6f9SApple OSS Distributions PULLBYTE();
567*bbb1b6f9SApple OSS Distributions }
568*bbb1b6f9SApple OSS Distributions DROPBITS(last.bits);
569*bbb1b6f9SApple OSS Distributions }
570*bbb1b6f9SApple OSS Distributions DROPBITS(this.bits);
571*bbb1b6f9SApple OSS Distributions if (this.op & 64) {
572*bbb1b6f9SApple OSS Distributions strm->msg = (char *)"invalid distance code";
573*bbb1b6f9SApple OSS Distributions state->mode = BAD;
574*bbb1b6f9SApple OSS Distributions break;
575*bbb1b6f9SApple OSS Distributions }
576*bbb1b6f9SApple OSS Distributions state->offset = (unsigned)this.val;
577*bbb1b6f9SApple OSS Distributions
578*bbb1b6f9SApple OSS Distributions /* get distance extra bits, if any */
579*bbb1b6f9SApple OSS Distributions state->extra = (unsigned)(this.op) & 15;
580*bbb1b6f9SApple OSS Distributions if (state->extra != 0) {
581*bbb1b6f9SApple OSS Distributions NEEDBITS(state->extra);
582*bbb1b6f9SApple OSS Distributions state->offset += BITS(state->extra);
583*bbb1b6f9SApple OSS Distributions DROPBITS(state->extra);
584*bbb1b6f9SApple OSS Distributions }
585*bbb1b6f9SApple OSS Distributions if (state->offset > state->wsize - (state->whave < state->wsize ?
586*bbb1b6f9SApple OSS Distributions left : 0)) {
587*bbb1b6f9SApple OSS Distributions strm->msg = (char *)"invalid distance too far back";
588*bbb1b6f9SApple OSS Distributions state->mode = BAD;
589*bbb1b6f9SApple OSS Distributions break;
590*bbb1b6f9SApple OSS Distributions }
591*bbb1b6f9SApple OSS Distributions Tracevv((stderr, "inflate: distance %u\n", state->offset));
592*bbb1b6f9SApple OSS Distributions
593*bbb1b6f9SApple OSS Distributions /* copy match from window to output */
594*bbb1b6f9SApple OSS Distributions do {
595*bbb1b6f9SApple OSS Distributions ROOM();
596*bbb1b6f9SApple OSS Distributions copy = state->wsize - state->offset;
597*bbb1b6f9SApple OSS Distributions if (copy < left) {
598*bbb1b6f9SApple OSS Distributions from = put + copy;
599*bbb1b6f9SApple OSS Distributions copy = left - copy;
600*bbb1b6f9SApple OSS Distributions }
601*bbb1b6f9SApple OSS Distributions else {
602*bbb1b6f9SApple OSS Distributions from = put - state->offset;
603*bbb1b6f9SApple OSS Distributions copy = left;
604*bbb1b6f9SApple OSS Distributions }
605*bbb1b6f9SApple OSS Distributions if (copy > state->length) copy = state->length;
606*bbb1b6f9SApple OSS Distributions state->length -= copy;
607*bbb1b6f9SApple OSS Distributions left -= copy;
608*bbb1b6f9SApple OSS Distributions do {
609*bbb1b6f9SApple OSS Distributions *put++ = *from++;
610*bbb1b6f9SApple OSS Distributions } while (--copy);
611*bbb1b6f9SApple OSS Distributions } while (state->length != 0);
612*bbb1b6f9SApple OSS Distributions break;
613*bbb1b6f9SApple OSS Distributions
614*bbb1b6f9SApple OSS Distributions case DONE:
615*bbb1b6f9SApple OSS Distributions /* inflate stream terminated properly -- write leftover output */
616*bbb1b6f9SApple OSS Distributions ret = Z_STREAM_END;
617*bbb1b6f9SApple OSS Distributions if (left < state->wsize) {
618*bbb1b6f9SApple OSS Distributions if (out(out_desc, state->window, state->wsize - left))
619*bbb1b6f9SApple OSS Distributions ret = Z_BUF_ERROR;
620*bbb1b6f9SApple OSS Distributions }
621*bbb1b6f9SApple OSS Distributions goto inf_leave;
622*bbb1b6f9SApple OSS Distributions
623*bbb1b6f9SApple OSS Distributions case BAD:
624*bbb1b6f9SApple OSS Distributions ret = Z_DATA_ERROR;
625*bbb1b6f9SApple OSS Distributions goto inf_leave;
626*bbb1b6f9SApple OSS Distributions
627*bbb1b6f9SApple OSS Distributions default: /* can't happen, but makes compilers happy */
628*bbb1b6f9SApple OSS Distributions ret = Z_STREAM_ERROR;
629*bbb1b6f9SApple OSS Distributions goto inf_leave;
630*bbb1b6f9SApple OSS Distributions }
631*bbb1b6f9SApple OSS Distributions
632*bbb1b6f9SApple OSS Distributions /* Return unused input */
633*bbb1b6f9SApple OSS Distributions inf_leave:
634*bbb1b6f9SApple OSS Distributions strm->next_in = next;
635*bbb1b6f9SApple OSS Distributions strm->avail_in = have;
636*bbb1b6f9SApple OSS Distributions return ret;
637*bbb1b6f9SApple OSS Distributions }
638*bbb1b6f9SApple OSS Distributions
639*bbb1b6f9SApple OSS Distributions int ZEXPORT
inflateBackEnd(z_streamp strm)640*bbb1b6f9SApple OSS Distributions inflateBackEnd(z_streamp strm)
641*bbb1b6f9SApple OSS Distributions {
642*bbb1b6f9SApple OSS Distributions if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
643*bbb1b6f9SApple OSS Distributions return Z_STREAM_ERROR;
644*bbb1b6f9SApple OSS Distributions ZFREE(strm, strm->state);
645*bbb1b6f9SApple OSS Distributions strm->state = Z_NULL;
646*bbb1b6f9SApple OSS Distributions Tracev((stderr, "inflate: end\n"));
647*bbb1b6f9SApple OSS Distributions return Z_OK;
648*bbb1b6f9SApple OSS Distributions }
649