xref: /netbsd-src/external/gpl3/binutils.old/dist/zlib/infback.c (revision e992f068c547fd6e84b3f104dc2340adcc955732)
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