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