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