175fd0b74Schristos /* infback.c -- inflate using a call-back interface
2*e992f068Schristos * Copyright (C) 1995-2022 Mark Adler
375fd0b74Schristos * For conditions of distribution and use, see copyright notice in zlib.h
475fd0b74Schristos */
575fd0b74Schristos
675fd0b74Schristos /*
775fd0b74Schristos This code is largely copied from inflate.c. Normally either infback.o or
875fd0b74Schristos inflate.o would be linked into an application--not both. The interface
975fd0b74Schristos with inffast.c is retained so that optimized assembler-coded versions of
1075fd0b74Schristos inflate_fast() can be used with either inflate.c or infback.c.
1175fd0b74Schristos */
1275fd0b74Schristos
1375fd0b74Schristos #include "zutil.h"
1475fd0b74Schristos #include "inftrees.h"
1575fd0b74Schristos #include "inflate.h"
1675fd0b74Schristos #include "inffast.h"
1775fd0b74Schristos
1875fd0b74Schristos /* function prototypes */
1975fd0b74Schristos local void fixedtables OF((struct inflate_state FAR *state));
2075fd0b74Schristos
2175fd0b74Schristos /*
2275fd0b74Schristos strm provides memory allocation functions in zalloc and zfree, or
2375fd0b74Schristos Z_NULL to use the library memory allocation functions.
2475fd0b74Schristos
2575fd0b74Schristos windowBits is in the range 8..15, and window is a user-supplied
2675fd0b74Schristos window and output buffer that is 2**windowBits bytes.
2775fd0b74Schristos */
inflateBackInit_(strm,windowBits,window,version,stream_size)2875fd0b74Schristos int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
2975fd0b74Schristos z_streamp strm;
3075fd0b74Schristos int windowBits;
3175fd0b74Schristos unsigned char FAR *window;
3275fd0b74Schristos const char *version;
3375fd0b74Schristos int stream_size;
3475fd0b74Schristos {
3575fd0b74Schristos struct inflate_state FAR *state;
3675fd0b74Schristos
3775fd0b74Schristos if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
3875fd0b74Schristos stream_size != (int)(sizeof(z_stream)))
3975fd0b74Schristos return Z_VERSION_ERROR;
4075fd0b74Schristos if (strm == Z_NULL || window == Z_NULL ||
4175fd0b74Schristos windowBits < 8 || windowBits > 15)
4275fd0b74Schristos return Z_STREAM_ERROR;
4375fd0b74Schristos strm->msg = Z_NULL; /* in case we return an error */
4475fd0b74Schristos if (strm->zalloc == (alloc_func)0) {
4575fd0b74Schristos #ifdef Z_SOLO
4675fd0b74Schristos return Z_STREAM_ERROR;
4775fd0b74Schristos #else
4875fd0b74Schristos strm->zalloc = zcalloc;
4975fd0b74Schristos strm->opaque = (voidpf)0;
5075fd0b74Schristos #endif
5175fd0b74Schristos }
5275fd0b74Schristos if (strm->zfree == (free_func)0)
5375fd0b74Schristos #ifdef Z_SOLO
5475fd0b74Schristos return Z_STREAM_ERROR;
5575fd0b74Schristos #else
5675fd0b74Schristos strm->zfree = zcfree;
5775fd0b74Schristos #endif
5875fd0b74Schristos state = (struct inflate_state FAR *)ZALLOC(strm, 1,
5975fd0b74Schristos sizeof(struct inflate_state));
6075fd0b74Schristos if (state == Z_NULL) return Z_MEM_ERROR;
6175fd0b74Schristos Tracev((stderr, "inflate: allocated\n"));
6275fd0b74Schristos strm->state = (struct internal_state FAR *)state;
6375fd0b74Schristos state->dmax = 32768U;
64ede78133Schristos state->wbits = (uInt)windowBits;
6575fd0b74Schristos state->wsize = 1U << windowBits;
6675fd0b74Schristos state->window = window;
6775fd0b74Schristos state->wnext = 0;
6875fd0b74Schristos state->whave = 0;
6975fd0b74Schristos return Z_OK;
7075fd0b74Schristos }
7175fd0b74Schristos
7275fd0b74Schristos /*
7375fd0b74Schristos Return state with length and distance decoding tables and index sizes set to
7475fd0b74Schristos fixed code decoding. Normally this returns fixed tables from inffixed.h.
7575fd0b74Schristos If BUILDFIXED is defined, then instead this routine builds the tables the
7675fd0b74Schristos first time it's called, and returns those tables the first time and
7775fd0b74Schristos thereafter. This reduces the size of the code by about 2K bytes, in
7875fd0b74Schristos exchange for a little execution time. However, BUILDFIXED should not be
7975fd0b74Schristos used for threaded applications, since the rewriting of the tables and virgin
8075fd0b74Schristos may not be thread-safe.
8175fd0b74Schristos */
fixedtables(state)8275fd0b74Schristos local void fixedtables(state)
8375fd0b74Schristos struct inflate_state FAR *state;
8475fd0b74Schristos {
8575fd0b74Schristos #ifdef BUILDFIXED
8675fd0b74Schristos static int virgin = 1;
8775fd0b74Schristos static code *lenfix, *distfix;
8875fd0b74Schristos static code fixed[544];
8975fd0b74Schristos
9075fd0b74Schristos /* build fixed huffman tables if first call (may not be thread safe) */
9175fd0b74Schristos if (virgin) {
9275fd0b74Schristos unsigned sym, bits;
9375fd0b74Schristos static code *next;
9475fd0b74Schristos
9575fd0b74Schristos /* literal/length table */
9675fd0b74Schristos sym = 0;
9775fd0b74Schristos while (sym < 144) state->lens[sym++] = 8;
9875fd0b74Schristos while (sym < 256) state->lens[sym++] = 9;
9975fd0b74Schristos while (sym < 280) state->lens[sym++] = 7;
10075fd0b74Schristos while (sym < 288) state->lens[sym++] = 8;
10175fd0b74Schristos next = fixed;
10275fd0b74Schristos lenfix = next;
10375fd0b74Schristos bits = 9;
10475fd0b74Schristos inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
10575fd0b74Schristos
10675fd0b74Schristos /* distance table */
10775fd0b74Schristos sym = 0;
10875fd0b74Schristos while (sym < 32) state->lens[sym++] = 5;
10975fd0b74Schristos distfix = next;
11075fd0b74Schristos bits = 5;
11175fd0b74Schristos inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
11275fd0b74Schristos
11375fd0b74Schristos /* do this just once */
11475fd0b74Schristos virgin = 0;
11575fd0b74Schristos }
11675fd0b74Schristos #else /* !BUILDFIXED */
11775fd0b74Schristos # include "inffixed.h"
11875fd0b74Schristos #endif /* BUILDFIXED */
11975fd0b74Schristos state->lencode = lenfix;
12075fd0b74Schristos state->lenbits = 9;
12175fd0b74Schristos state->distcode = distfix;
12275fd0b74Schristos state->distbits = 5;
12375fd0b74Schristos }
12475fd0b74Schristos
12575fd0b74Schristos /* Macros for inflateBack(): */
12675fd0b74Schristos
12775fd0b74Schristos /* Load returned state from inflate_fast() */
12875fd0b74Schristos #define LOAD() \
12975fd0b74Schristos do { \
13075fd0b74Schristos put = strm->next_out; \
13175fd0b74Schristos left = strm->avail_out; \
13275fd0b74Schristos next = strm->next_in; \
13375fd0b74Schristos have = strm->avail_in; \
13475fd0b74Schristos hold = state->hold; \
13575fd0b74Schristos bits = state->bits; \
13675fd0b74Schristos } while (0)
13775fd0b74Schristos
13875fd0b74Schristos /* Set state from registers for inflate_fast() */
13975fd0b74Schristos #define RESTORE() \
14075fd0b74Schristos do { \
14175fd0b74Schristos strm->next_out = put; \
14275fd0b74Schristos strm->avail_out = left; \
14375fd0b74Schristos strm->next_in = next; \
14475fd0b74Schristos strm->avail_in = have; \
14575fd0b74Schristos state->hold = hold; \
14675fd0b74Schristos state->bits = bits; \
14775fd0b74Schristos } while (0)
14875fd0b74Schristos
14975fd0b74Schristos /* Clear the input bit accumulator */
15075fd0b74Schristos #define INITBITS() \
15175fd0b74Schristos do { \
15275fd0b74Schristos hold = 0; \
15375fd0b74Schristos bits = 0; \
15475fd0b74Schristos } while (0)
15575fd0b74Schristos
15675fd0b74Schristos /* Assure that some input is available. If input is requested, but denied,
15775fd0b74Schristos then return a Z_BUF_ERROR from inflateBack(). */
15875fd0b74Schristos #define PULL() \
15975fd0b74Schristos do { \
16075fd0b74Schristos if (have == 0) { \
16175fd0b74Schristos have = in(in_desc, &next); \
16275fd0b74Schristos if (have == 0) { \
16375fd0b74Schristos next = Z_NULL; \
16475fd0b74Schristos ret = Z_BUF_ERROR; \
16575fd0b74Schristos goto inf_leave; \
16675fd0b74Schristos } \
16775fd0b74Schristos } \
16875fd0b74Schristos } while (0)
16975fd0b74Schristos
17075fd0b74Schristos /* Get a byte of input into the bit accumulator, or return from inflateBack()
17175fd0b74Schristos with an error if there is no input available. */
17275fd0b74Schristos #define PULLBYTE() \
17375fd0b74Schristos do { \
17475fd0b74Schristos PULL(); \
17575fd0b74Schristos have--; \
17675fd0b74Schristos hold += (unsigned long)(*next++) << bits; \
17775fd0b74Schristos bits += 8; \
17875fd0b74Schristos } while (0)
17975fd0b74Schristos
18075fd0b74Schristos /* Assure that there are at least n bits in the bit accumulator. If there is
18175fd0b74Schristos not enough available input to do that, then return from inflateBack() with
18275fd0b74Schristos an error. */
18375fd0b74Schristos #define NEEDBITS(n) \
18475fd0b74Schristos do { \
18575fd0b74Schristos while (bits < (unsigned)(n)) \
18675fd0b74Schristos PULLBYTE(); \
18775fd0b74Schristos } while (0)
18875fd0b74Schristos
18975fd0b74Schristos /* Return the low n bits of the bit accumulator (n < 16) */
19075fd0b74Schristos #define BITS(n) \
19175fd0b74Schristos ((unsigned)hold & ((1U << (n)) - 1))
19275fd0b74Schristos
19375fd0b74Schristos /* Remove n bits from the bit accumulator */
19475fd0b74Schristos #define DROPBITS(n) \
19575fd0b74Schristos do { \
19675fd0b74Schristos hold >>= (n); \
19775fd0b74Schristos bits -= (unsigned)(n); \
19875fd0b74Schristos } while (0)
19975fd0b74Schristos
20075fd0b74Schristos /* Remove zero to seven bits as needed to go to a byte boundary */
20175fd0b74Schristos #define BYTEBITS() \
20275fd0b74Schristos do { \
20375fd0b74Schristos hold >>= bits & 7; \
20475fd0b74Schristos bits -= bits & 7; \
20575fd0b74Schristos } while (0)
20675fd0b74Schristos
20775fd0b74Schristos /* Assure that some output space is available, by writing out the window
20875fd0b74Schristos if it's full. If the write fails, return from inflateBack() with a
20975fd0b74Schristos Z_BUF_ERROR. */
21075fd0b74Schristos #define ROOM() \
21175fd0b74Schristos do { \
21275fd0b74Schristos if (left == 0) { \
21375fd0b74Schristos put = state->window; \
21475fd0b74Schristos left = state->wsize; \
21575fd0b74Schristos state->whave = left; \
21675fd0b74Schristos if (out(out_desc, put, left)) { \
21775fd0b74Schristos ret = Z_BUF_ERROR; \
21875fd0b74Schristos goto inf_leave; \
21975fd0b74Schristos } \
22075fd0b74Schristos } \
22175fd0b74Schristos } while (0)
22275fd0b74Schristos
22375fd0b74Schristos /*
22475fd0b74Schristos strm provides the memory allocation functions and window buffer on input,
22575fd0b74Schristos and provides information on the unused input on return. For Z_DATA_ERROR
22675fd0b74Schristos returns, strm will also provide an error message.
22775fd0b74Schristos
22875fd0b74Schristos in() and out() are the call-back input and output functions. When
22975fd0b74Schristos inflateBack() needs more input, it calls in(). When inflateBack() has
23075fd0b74Schristos filled the window with output, or when it completes with data in the
23175fd0b74Schristos window, it calls out() to write out the data. The application must not
23275fd0b74Schristos change the provided input until in() is called again or inflateBack()
23375fd0b74Schristos returns. The application must not change the window/output buffer until
23475fd0b74Schristos inflateBack() returns.
23575fd0b74Schristos
23675fd0b74Schristos in() and out() are called with a descriptor parameter provided in the
23775fd0b74Schristos inflateBack() call. This parameter can be a structure that provides the
23875fd0b74Schristos information required to do the read or write, as well as accumulated
23975fd0b74Schristos information on the input and output such as totals and check values.
24075fd0b74Schristos
24175fd0b74Schristos in() should return zero on failure. out() should return non-zero on
24275fd0b74Schristos failure. If either in() or out() fails, than inflateBack() returns a
24375fd0b74Schristos Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
24475fd0b74Schristos was in() or out() that caused in the error. Otherwise, inflateBack()
24575fd0b74Schristos returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
24675fd0b74Schristos error, or Z_MEM_ERROR if it could not allocate memory for the state.
24775fd0b74Schristos inflateBack() can also return Z_STREAM_ERROR if the input parameters
24875fd0b74Schristos are not correct, i.e. strm is Z_NULL or the state was not initialized.
24975fd0b74Schristos */
inflateBack(strm,in,in_desc,out,out_desc)25075fd0b74Schristos int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
25175fd0b74Schristos z_streamp strm;
25275fd0b74Schristos in_func in;
25375fd0b74Schristos void FAR *in_desc;
25475fd0b74Schristos out_func out;
25575fd0b74Schristos void FAR *out_desc;
25675fd0b74Schristos {
25775fd0b74Schristos struct inflate_state FAR *state;
25875fd0b74Schristos z_const unsigned char FAR *next; /* next input */
25975fd0b74Schristos unsigned char FAR *put; /* next output */
26075fd0b74Schristos unsigned have, left; /* available input and output */
26175fd0b74Schristos unsigned long hold; /* bit buffer */
26275fd0b74Schristos unsigned bits; /* bits in bit buffer */
26375fd0b74Schristos unsigned copy; /* number of stored or match bytes to copy */
26475fd0b74Schristos unsigned char FAR *from; /* where to copy match bytes from */
26575fd0b74Schristos code here; /* current decoding table entry */
26675fd0b74Schristos code last; /* parent table entry */
26775fd0b74Schristos unsigned len; /* length to copy for repeats, bits to drop */
26875fd0b74Schristos int ret; /* return code */
26975fd0b74Schristos static const unsigned short order[19] = /* permutation of code lengths */
27075fd0b74Schristos {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
27175fd0b74Schristos
27275fd0b74Schristos /* Check that the strm exists and that the state was initialized */
27375fd0b74Schristos if (strm == Z_NULL || strm->state == Z_NULL)
27475fd0b74Schristos return Z_STREAM_ERROR;
27575fd0b74Schristos state = (struct inflate_state FAR *)strm->state;
27675fd0b74Schristos
27775fd0b74Schristos /* Reset the state */
27875fd0b74Schristos strm->msg = Z_NULL;
27975fd0b74Schristos state->mode = TYPE;
28075fd0b74Schristos state->last = 0;
28175fd0b74Schristos state->whave = 0;
28275fd0b74Schristos next = strm->next_in;
28375fd0b74Schristos have = next != Z_NULL ? strm->avail_in : 0;
28475fd0b74Schristos hold = 0;
28575fd0b74Schristos bits = 0;
28675fd0b74Schristos put = state->window;
28775fd0b74Schristos left = state->wsize;
28875fd0b74Schristos
28975fd0b74Schristos /* Inflate until end of block marked as last */
29075fd0b74Schristos for (;;)
29175fd0b74Schristos switch (state->mode) {
29275fd0b74Schristos case TYPE:
29375fd0b74Schristos /* determine and dispatch block type */
29475fd0b74Schristos if (state->last) {
29575fd0b74Schristos BYTEBITS();
29675fd0b74Schristos state->mode = DONE;
29775fd0b74Schristos break;
29875fd0b74Schristos }
29975fd0b74Schristos NEEDBITS(3);
30075fd0b74Schristos state->last = BITS(1);
30175fd0b74Schristos DROPBITS(1);
30275fd0b74Schristos switch (BITS(2)) {
30375fd0b74Schristos case 0: /* stored block */
30475fd0b74Schristos Tracev((stderr, "inflate: stored block%s\n",
30575fd0b74Schristos state->last ? " (last)" : ""));
30675fd0b74Schristos state->mode = STORED;
30775fd0b74Schristos break;
30875fd0b74Schristos case 1: /* fixed block */
30975fd0b74Schristos fixedtables(state);
31075fd0b74Schristos Tracev((stderr, "inflate: fixed codes block%s\n",
31175fd0b74Schristos state->last ? " (last)" : ""));
31275fd0b74Schristos state->mode = LEN; /* decode codes */
31375fd0b74Schristos break;
31475fd0b74Schristos case 2: /* dynamic block */
31575fd0b74Schristos Tracev((stderr, "inflate: dynamic codes block%s\n",
31675fd0b74Schristos state->last ? " (last)" : ""));
31775fd0b74Schristos state->mode = TABLE;
31875fd0b74Schristos break;
31975fd0b74Schristos case 3:
32075fd0b74Schristos strm->msg = (char *)"invalid block type";
32175fd0b74Schristos state->mode = BAD;
32275fd0b74Schristos }
32375fd0b74Schristos DROPBITS(2);
32475fd0b74Schristos break;
32575fd0b74Schristos
32675fd0b74Schristos case STORED:
32775fd0b74Schristos /* get and verify stored block length */
32875fd0b74Schristos BYTEBITS(); /* go to byte boundary */
32975fd0b74Schristos NEEDBITS(32);
33075fd0b74Schristos if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
33175fd0b74Schristos strm->msg = (char *)"invalid stored block lengths";
33275fd0b74Schristos state->mode = BAD;
33375fd0b74Schristos break;
33475fd0b74Schristos }
33575fd0b74Schristos state->length = (unsigned)hold & 0xffff;
33675fd0b74Schristos Tracev((stderr, "inflate: stored length %u\n",
33775fd0b74Schristos state->length));
33875fd0b74Schristos INITBITS();
33975fd0b74Schristos
34075fd0b74Schristos /* copy stored block from input to output */
34175fd0b74Schristos while (state->length != 0) {
34275fd0b74Schristos copy = state->length;
34375fd0b74Schristos PULL();
34475fd0b74Schristos ROOM();
34575fd0b74Schristos if (copy > have) copy = have;
34675fd0b74Schristos if (copy > left) copy = left;
34775fd0b74Schristos zmemcpy(put, next, copy);
34875fd0b74Schristos have -= copy;
34975fd0b74Schristos next += copy;
35075fd0b74Schristos left -= copy;
35175fd0b74Schristos put += copy;
35275fd0b74Schristos state->length -= copy;
35375fd0b74Schristos }
35475fd0b74Schristos Tracev((stderr, "inflate: stored end\n"));
35575fd0b74Schristos state->mode = TYPE;
35675fd0b74Schristos break;
35775fd0b74Schristos
35875fd0b74Schristos case TABLE:
35975fd0b74Schristos /* get dynamic table entries descriptor */
36075fd0b74Schristos NEEDBITS(14);
36175fd0b74Schristos state->nlen = BITS(5) + 257;
36275fd0b74Schristos DROPBITS(5);
36375fd0b74Schristos state->ndist = BITS(5) + 1;
36475fd0b74Schristos DROPBITS(5);
36575fd0b74Schristos state->ncode = BITS(4) + 4;
36675fd0b74Schristos DROPBITS(4);
36775fd0b74Schristos #ifndef PKZIP_BUG_WORKAROUND
36875fd0b74Schristos if (state->nlen > 286 || state->ndist > 30) {
36975fd0b74Schristos strm->msg = (char *)"too many length or distance symbols";
37075fd0b74Schristos state->mode = BAD;
37175fd0b74Schristos break;
37275fd0b74Schristos }
37375fd0b74Schristos #endif
37475fd0b74Schristos Tracev((stderr, "inflate: table sizes ok\n"));
37575fd0b74Schristos
37675fd0b74Schristos /* get code length code lengths (not a typo) */
37775fd0b74Schristos state->have = 0;
37875fd0b74Schristos while (state->have < state->ncode) {
37975fd0b74Schristos NEEDBITS(3);
38075fd0b74Schristos state->lens[order[state->have++]] = (unsigned short)BITS(3);
38175fd0b74Schristos DROPBITS(3);
38275fd0b74Schristos }
38375fd0b74Schristos while (state->have < 19)
38475fd0b74Schristos state->lens[order[state->have++]] = 0;
38575fd0b74Schristos state->next = state->codes;
38675fd0b74Schristos state->lencode = (code const FAR *)(state->next);
38775fd0b74Schristos state->lenbits = 7;
38875fd0b74Schristos ret = inflate_table(CODES, state->lens, 19, &(state->next),
38975fd0b74Schristos &(state->lenbits), state->work);
39075fd0b74Schristos if (ret) {
39175fd0b74Schristos strm->msg = (char *)"invalid code lengths set";
39275fd0b74Schristos state->mode = BAD;
39375fd0b74Schristos break;
39475fd0b74Schristos }
39575fd0b74Schristos Tracev((stderr, "inflate: code lengths ok\n"));
39675fd0b74Schristos
39775fd0b74Schristos /* get length and distance code code lengths */
39875fd0b74Schristos state->have = 0;
39975fd0b74Schristos while (state->have < state->nlen + state->ndist) {
40075fd0b74Schristos for (;;) {
40175fd0b74Schristos here = state->lencode[BITS(state->lenbits)];
40275fd0b74Schristos if ((unsigned)(here.bits) <= bits) break;
40375fd0b74Schristos PULLBYTE();
40475fd0b74Schristos }
40575fd0b74Schristos if (here.val < 16) {
40675fd0b74Schristos DROPBITS(here.bits);
40775fd0b74Schristos state->lens[state->have++] = here.val;
40875fd0b74Schristos }
40975fd0b74Schristos else {
41075fd0b74Schristos if (here.val == 16) {
41175fd0b74Schristos NEEDBITS(here.bits + 2);
41275fd0b74Schristos DROPBITS(here.bits);
41375fd0b74Schristos if (state->have == 0) {
41475fd0b74Schristos strm->msg = (char *)"invalid bit length repeat";
41575fd0b74Schristos state->mode = BAD;
41675fd0b74Schristos break;
41775fd0b74Schristos }
41875fd0b74Schristos len = (unsigned)(state->lens[state->have - 1]);
41975fd0b74Schristos copy = 3 + BITS(2);
42075fd0b74Schristos DROPBITS(2);
42175fd0b74Schristos }
42275fd0b74Schristos else if (here.val == 17) {
42375fd0b74Schristos NEEDBITS(here.bits + 3);
42475fd0b74Schristos DROPBITS(here.bits);
42575fd0b74Schristos len = 0;
42675fd0b74Schristos copy = 3 + BITS(3);
42775fd0b74Schristos DROPBITS(3);
42875fd0b74Schristos }
42975fd0b74Schristos else {
43075fd0b74Schristos NEEDBITS(here.bits + 7);
43175fd0b74Schristos DROPBITS(here.bits);
43275fd0b74Schristos len = 0;
43375fd0b74Schristos copy = 11 + BITS(7);
43475fd0b74Schristos DROPBITS(7);
43575fd0b74Schristos }
43675fd0b74Schristos if (state->have + copy > state->nlen + state->ndist) {
43775fd0b74Schristos strm->msg = (char *)"invalid bit length repeat";
43875fd0b74Schristos state->mode = BAD;
43975fd0b74Schristos break;
44075fd0b74Schristos }
44175fd0b74Schristos while (copy--)
44275fd0b74Schristos state->lens[state->have++] = (unsigned short)len;
44375fd0b74Schristos }
44475fd0b74Schristos }
44575fd0b74Schristos
44675fd0b74Schristos /* handle error breaks in while */
44775fd0b74Schristos if (state->mode == BAD) break;
44875fd0b74Schristos
44975fd0b74Schristos /* check for end-of-block code (better have one) */
45075fd0b74Schristos if (state->lens[256] == 0) {
45175fd0b74Schristos strm->msg = (char *)"invalid code -- missing end-of-block";
45275fd0b74Schristos state->mode = BAD;
45375fd0b74Schristos break;
45475fd0b74Schristos }
45575fd0b74Schristos
45675fd0b74Schristos /* build code tables -- note: do not change the lenbits or distbits
45775fd0b74Schristos values here (9 and 6) without reading the comments in inftrees.h
45875fd0b74Schristos concerning the ENOUGH constants, which depend on those values */
45975fd0b74Schristos state->next = state->codes;
46075fd0b74Schristos state->lencode = (code const FAR *)(state->next);
46175fd0b74Schristos state->lenbits = 9;
46275fd0b74Schristos ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
46375fd0b74Schristos &(state->lenbits), state->work);
46475fd0b74Schristos if (ret) {
46575fd0b74Schristos strm->msg = (char *)"invalid literal/lengths set";
46675fd0b74Schristos state->mode = BAD;
46775fd0b74Schristos break;
46875fd0b74Schristos }
46975fd0b74Schristos state->distcode = (code const FAR *)(state->next);
47075fd0b74Schristos state->distbits = 6;
47175fd0b74Schristos ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
47275fd0b74Schristos &(state->next), &(state->distbits), state->work);
47375fd0b74Schristos if (ret) {
47475fd0b74Schristos strm->msg = (char *)"invalid distances set";
47575fd0b74Schristos state->mode = BAD;
47675fd0b74Schristos break;
47775fd0b74Schristos }
47875fd0b74Schristos Tracev((stderr, "inflate: codes ok\n"));
47975fd0b74Schristos state->mode = LEN;
480*e992f068Schristos /* fallthrough */
48175fd0b74Schristos
48275fd0b74Schristos case LEN:
48375fd0b74Schristos /* use inflate_fast() if we have enough input and output */
48475fd0b74Schristos if (have >= 6 && left >= 258) {
48575fd0b74Schristos RESTORE();
48675fd0b74Schristos if (state->whave < state->wsize)
48775fd0b74Schristos state->whave = state->wsize - left;
48875fd0b74Schristos inflate_fast(strm, state->wsize);
48975fd0b74Schristos LOAD();
49075fd0b74Schristos break;
49175fd0b74Schristos }
49275fd0b74Schristos
49375fd0b74Schristos /* get a literal, length, or end-of-block code */
49475fd0b74Schristos for (;;) {
49575fd0b74Schristos here = state->lencode[BITS(state->lenbits)];
49675fd0b74Schristos if ((unsigned)(here.bits) <= bits) break;
49775fd0b74Schristos PULLBYTE();
49875fd0b74Schristos }
49975fd0b74Schristos if (here.op && (here.op & 0xf0) == 0) {
50075fd0b74Schristos last = here;
50175fd0b74Schristos for (;;) {
50275fd0b74Schristos here = state->lencode[last.val +
50375fd0b74Schristos (BITS(last.bits + last.op) >> last.bits)];
50475fd0b74Schristos if ((unsigned)(last.bits + here.bits) <= bits) break;
50575fd0b74Schristos PULLBYTE();
50675fd0b74Schristos }
50775fd0b74Schristos DROPBITS(last.bits);
50875fd0b74Schristos }
50975fd0b74Schristos DROPBITS(here.bits);
51075fd0b74Schristos state->length = (unsigned)here.val;
51175fd0b74Schristos
51275fd0b74Schristos /* process literal */
51375fd0b74Schristos if (here.op == 0) {
51475fd0b74Schristos Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
51575fd0b74Schristos "inflate: literal '%c'\n" :
51675fd0b74Schristos "inflate: literal 0x%02x\n", here.val));
51775fd0b74Schristos ROOM();
51875fd0b74Schristos *put++ = (unsigned char)(state->length);
51975fd0b74Schristos left--;
52075fd0b74Schristos state->mode = LEN;
52175fd0b74Schristos break;
52275fd0b74Schristos }
52375fd0b74Schristos
52475fd0b74Schristos /* process end of block */
52575fd0b74Schristos if (here.op & 32) {
52675fd0b74Schristos Tracevv((stderr, "inflate: end of block\n"));
52775fd0b74Schristos state->mode = TYPE;
52875fd0b74Schristos break;
52975fd0b74Schristos }
53075fd0b74Schristos
53175fd0b74Schristos /* invalid code */
53275fd0b74Schristos if (here.op & 64) {
53375fd0b74Schristos strm->msg = (char *)"invalid literal/length code";
53475fd0b74Schristos state->mode = BAD;
53575fd0b74Schristos break;
53675fd0b74Schristos }
53775fd0b74Schristos
53875fd0b74Schristos /* length code -- get extra bits, if any */
53975fd0b74Schristos state->extra = (unsigned)(here.op) & 15;
54075fd0b74Schristos if (state->extra != 0) {
54175fd0b74Schristos NEEDBITS(state->extra);
54275fd0b74Schristos state->length += BITS(state->extra);
54375fd0b74Schristos DROPBITS(state->extra);
54475fd0b74Schristos }
54575fd0b74Schristos Tracevv((stderr, "inflate: length %u\n", state->length));
54675fd0b74Schristos
54775fd0b74Schristos /* get distance code */
54875fd0b74Schristos for (;;) {
54975fd0b74Schristos here = state->distcode[BITS(state->distbits)];
55075fd0b74Schristos if ((unsigned)(here.bits) <= bits) break;
55175fd0b74Schristos PULLBYTE();
55275fd0b74Schristos }
55375fd0b74Schristos if ((here.op & 0xf0) == 0) {
55475fd0b74Schristos last = here;
55575fd0b74Schristos for (;;) {
55675fd0b74Schristos here = state->distcode[last.val +
55775fd0b74Schristos (BITS(last.bits + last.op) >> last.bits)];
55875fd0b74Schristos if ((unsigned)(last.bits + here.bits) <= bits) break;
55975fd0b74Schristos PULLBYTE();
56075fd0b74Schristos }
56175fd0b74Schristos DROPBITS(last.bits);
56275fd0b74Schristos }
56375fd0b74Schristos DROPBITS(here.bits);
56475fd0b74Schristos if (here.op & 64) {
56575fd0b74Schristos strm->msg = (char *)"invalid distance code";
56675fd0b74Schristos state->mode = BAD;
56775fd0b74Schristos break;
56875fd0b74Schristos }
56975fd0b74Schristos state->offset = (unsigned)here.val;
57075fd0b74Schristos
57175fd0b74Schristos /* get distance extra bits, if any */
57275fd0b74Schristos state->extra = (unsigned)(here.op) & 15;
57375fd0b74Schristos if (state->extra != 0) {
57475fd0b74Schristos NEEDBITS(state->extra);
57575fd0b74Schristos state->offset += BITS(state->extra);
57675fd0b74Schristos DROPBITS(state->extra);
57775fd0b74Schristos }
57875fd0b74Schristos if (state->offset > state->wsize - (state->whave < state->wsize ?
57975fd0b74Schristos left : 0)) {
58075fd0b74Schristos strm->msg = (char *)"invalid distance too far back";
58175fd0b74Schristos state->mode = BAD;
58275fd0b74Schristos break;
58375fd0b74Schristos }
58475fd0b74Schristos Tracevv((stderr, "inflate: distance %u\n", state->offset));
58575fd0b74Schristos
58675fd0b74Schristos /* copy match from window to output */
58775fd0b74Schristos do {
58875fd0b74Schristos ROOM();
58975fd0b74Schristos copy = state->wsize - state->offset;
59075fd0b74Schristos if (copy < left) {
59175fd0b74Schristos from = put + copy;
59275fd0b74Schristos copy = left - copy;
59375fd0b74Schristos }
59475fd0b74Schristos else {
59575fd0b74Schristos from = put - state->offset;
59675fd0b74Schristos copy = left;
59775fd0b74Schristos }
59875fd0b74Schristos if (copy > state->length) copy = state->length;
59975fd0b74Schristos state->length -= copy;
60075fd0b74Schristos left -= copy;
60175fd0b74Schristos do {
60275fd0b74Schristos *put++ = *from++;
60375fd0b74Schristos } while (--copy);
60475fd0b74Schristos } while (state->length != 0);
60575fd0b74Schristos break;
60675fd0b74Schristos
60775fd0b74Schristos case DONE:
60875fd0b74Schristos /* inflate stream terminated properly -- write leftover output */
60975fd0b74Schristos ret = Z_STREAM_END;
61075fd0b74Schristos if (left < state->wsize) {
61175fd0b74Schristos if (out(out_desc, state->window, state->wsize - left))
61275fd0b74Schristos ret = Z_BUF_ERROR;
61375fd0b74Schristos }
61475fd0b74Schristos goto inf_leave;
61575fd0b74Schristos
61675fd0b74Schristos case BAD:
61775fd0b74Schristos ret = Z_DATA_ERROR;
61875fd0b74Schristos goto inf_leave;
61975fd0b74Schristos
62075fd0b74Schristos default: /* can't happen, but makes compilers happy */
62175fd0b74Schristos ret = Z_STREAM_ERROR;
62275fd0b74Schristos goto inf_leave;
62375fd0b74Schristos }
62475fd0b74Schristos
62575fd0b74Schristos /* Return unused input */
62675fd0b74Schristos inf_leave:
62775fd0b74Schristos strm->next_in = next;
62875fd0b74Schristos strm->avail_in = have;
62975fd0b74Schristos return ret;
63075fd0b74Schristos }
63175fd0b74Schristos
inflateBackEnd(strm)63275fd0b74Schristos int ZEXPORT inflateBackEnd(strm)
63375fd0b74Schristos z_streamp strm;
63475fd0b74Schristos {
63575fd0b74Schristos if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
63675fd0b74Schristos return Z_STREAM_ERROR;
63775fd0b74Schristos ZFREE(strm, strm->state);
63875fd0b74Schristos strm->state = Z_NULL;
63975fd0b74Schristos Tracev((stderr, "inflate: end\n"));
64075fd0b74Schristos return Z_OK;
64175fd0b74Schristos }
642