1*ab9e68a2SToomas Soome /* inflate.c -- zlib decompression 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 * Change history: 8*ab9e68a2SToomas Soome * 9*ab9e68a2SToomas Soome * 1.2.beta0 24 Nov 2002 10*ab9e68a2SToomas Soome * - First version -- complete rewrite of inflate to simplify code, avoid 11*ab9e68a2SToomas Soome * creation of window when not needed, minimize use of window when it is 12*ab9e68a2SToomas Soome * needed, make inffast.c even faster, implement gzip decoding, and to 13*ab9e68a2SToomas Soome * improve code readability and style over the previous zlib inflate code 14*ab9e68a2SToomas Soome * 15*ab9e68a2SToomas Soome * 1.2.beta1 25 Nov 2002 16*ab9e68a2SToomas Soome * - Use pointers for available input and output checking in inffast.c 17*ab9e68a2SToomas Soome * - Remove input and output counters in inffast.c 18*ab9e68a2SToomas Soome * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 19*ab9e68a2SToomas Soome * - Remove unnecessary second byte pull from length extra in inffast.c 20*ab9e68a2SToomas Soome * - Unroll direct copy to three copies per loop in inffast.c 21*ab9e68a2SToomas Soome * 22*ab9e68a2SToomas Soome * 1.2.beta2 4 Dec 2002 23*ab9e68a2SToomas Soome * - Change external routine names to reduce potential conflicts 24*ab9e68a2SToomas Soome * - Correct filename to inffixed.h for fixed tables in inflate.c 25*ab9e68a2SToomas Soome * - Make hbuf[] unsigned char to match parameter type in inflate.c 26*ab9e68a2SToomas Soome * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) 27*ab9e68a2SToomas Soome * to avoid negation problem on Alphas (64 bit) in inflate.c 28*ab9e68a2SToomas Soome * 29*ab9e68a2SToomas Soome * 1.2.beta3 22 Dec 2002 30*ab9e68a2SToomas Soome * - Add comments on state->bits assertion in inffast.c 31*ab9e68a2SToomas Soome * - Add comments on op field in inftrees.h 32*ab9e68a2SToomas Soome * - Fix bug in reuse of allocated window after inflateReset() 33*ab9e68a2SToomas Soome * - Remove bit fields--back to byte structure for speed 34*ab9e68a2SToomas Soome * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths 35*ab9e68a2SToomas Soome * - Change post-increments to pre-increments in inflate_fast(), PPC biased? 36*ab9e68a2SToomas Soome * - Add compile time option, POSTINC, to use post-increments instead (Intel?) 37*ab9e68a2SToomas Soome * - Make MATCH copy in inflate() much faster for when inflate_fast() not used 38*ab9e68a2SToomas Soome * - Use local copies of stream next and avail values, as well as local bit 39*ab9e68a2SToomas Soome * buffer and bit count in inflate()--for speed when inflate_fast() not used 40*ab9e68a2SToomas Soome * 41*ab9e68a2SToomas Soome * 1.2.beta4 1 Jan 2003 42*ab9e68a2SToomas Soome * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings 43*ab9e68a2SToomas Soome * - Move a comment on output buffer sizes from inffast.c to inflate.c 44*ab9e68a2SToomas Soome * - Add comments in inffast.c to introduce the inflate_fast() routine 45*ab9e68a2SToomas Soome * - Rearrange window copies in inflate_fast() for speed and simplification 46*ab9e68a2SToomas Soome * - Unroll last copy for window match in inflate_fast() 47*ab9e68a2SToomas Soome * - Use local copies of window variables in inflate_fast() for speed 48*ab9e68a2SToomas Soome * - Pull out common wnext == 0 case for speed in inflate_fast() 49*ab9e68a2SToomas Soome * - Make op and len in inflate_fast() unsigned for consistency 50*ab9e68a2SToomas Soome * - Add FAR to lcode and dcode declarations in inflate_fast() 51*ab9e68a2SToomas Soome * - Simplified bad distance check in inflate_fast() 52*ab9e68a2SToomas Soome * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new 53*ab9e68a2SToomas Soome * source file infback.c to provide a call-back interface to inflate for 54*ab9e68a2SToomas Soome * programs like gzip and unzip -- uses window as output buffer to avoid 55*ab9e68a2SToomas Soome * window copying 56*ab9e68a2SToomas Soome * 57*ab9e68a2SToomas Soome * 1.2.beta5 1 Jan 2003 58*ab9e68a2SToomas Soome * - Improved inflateBack() interface to allow the caller to provide initial 59*ab9e68a2SToomas Soome * input in strm. 60*ab9e68a2SToomas Soome * - Fixed stored blocks bug in inflateBack() 61*ab9e68a2SToomas Soome * 62*ab9e68a2SToomas Soome * 1.2.beta6 4 Jan 2003 63*ab9e68a2SToomas Soome * - Added comments in inffast.c on effectiveness of POSTINC 64*ab9e68a2SToomas Soome * - Typecasting all around to reduce compiler warnings 65*ab9e68a2SToomas Soome * - Changed loops from while (1) or do {} while (1) to for (;;), again to 66*ab9e68a2SToomas Soome * make compilers happy 67*ab9e68a2SToomas Soome * - Changed type of window in inflateBackInit() to unsigned char * 68*ab9e68a2SToomas Soome * 69*ab9e68a2SToomas Soome * 1.2.beta7 27 Jan 2003 70*ab9e68a2SToomas Soome * - Changed many types to unsigned or unsigned short to avoid warnings 71*ab9e68a2SToomas Soome * - Added inflateCopy() function 72*ab9e68a2SToomas Soome * 73*ab9e68a2SToomas Soome * 1.2.0 9 Mar 2003 74*ab9e68a2SToomas Soome * - Changed inflateBack() interface to provide separate opaque descriptors 75*ab9e68a2SToomas Soome * for the in() and out() functions 76*ab9e68a2SToomas Soome * - Changed inflateBack() argument and in_func typedef to swap the length 77*ab9e68a2SToomas Soome * and buffer address return values for the input function 78*ab9e68a2SToomas Soome * - Check next_in and next_out for Z_NULL on entry to inflate() 79*ab9e68a2SToomas Soome * 80*ab9e68a2SToomas Soome * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. 81*ab9e68a2SToomas Soome */ 82*ab9e68a2SToomas Soome 83*ab9e68a2SToomas Soome #include "zutil.h" 84*ab9e68a2SToomas Soome #include "inftrees.h" 85*ab9e68a2SToomas Soome #include "inflate.h" 86*ab9e68a2SToomas Soome #include "inffast.h" 87*ab9e68a2SToomas Soome 88*ab9e68a2SToomas Soome #ifdef MAKEFIXED 89*ab9e68a2SToomas Soome # ifndef BUILDFIXED 90*ab9e68a2SToomas Soome # define BUILDFIXED 91*ab9e68a2SToomas Soome # endif 92*ab9e68a2SToomas Soome #endif 93*ab9e68a2SToomas Soome 94*ab9e68a2SToomas Soome /* function prototypes */ 95*ab9e68a2SToomas Soome local int inflateStateCheck OF((z_streamp strm)); 96*ab9e68a2SToomas Soome local void fixedtables OF((struct inflate_state FAR *state)); 97*ab9e68a2SToomas Soome local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, 98*ab9e68a2SToomas Soome unsigned copy)); 99*ab9e68a2SToomas Soome #ifdef BUILDFIXED 100*ab9e68a2SToomas Soome void makefixed OF((void)); 101*ab9e68a2SToomas Soome #endif 102*ab9e68a2SToomas Soome local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, 103*ab9e68a2SToomas Soome unsigned len)); 104*ab9e68a2SToomas Soome 105*ab9e68a2SToomas Soome local int inflateStateCheck(z_streamp strm) 106*ab9e68a2SToomas Soome { 107*ab9e68a2SToomas Soome struct inflate_state FAR *state; 108*ab9e68a2SToomas Soome if (strm == Z_NULL || 109*ab9e68a2SToomas Soome strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) 110*ab9e68a2SToomas Soome return 1; 111*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 112*ab9e68a2SToomas Soome if (state == Z_NULL || state->strm != strm || 113*ab9e68a2SToomas Soome state->mode < HEAD || state->mode > SYNC) 114*ab9e68a2SToomas Soome return 1; 115*ab9e68a2SToomas Soome return 0; 116*ab9e68a2SToomas Soome } 117*ab9e68a2SToomas Soome 118*ab9e68a2SToomas Soome int ZEXPORT inflateResetKeep(z_streamp strm) 119*ab9e68a2SToomas Soome { 120*ab9e68a2SToomas Soome struct inflate_state FAR *state; 121*ab9e68a2SToomas Soome 122*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 123*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 124*ab9e68a2SToomas Soome strm->total_in = strm->total_out = state->total = 0; 125*ab9e68a2SToomas Soome strm->msg = Z_NULL; 126*ab9e68a2SToomas Soome if (state->wrap) /* to support ill-conceived Java test suite */ 127*ab9e68a2SToomas Soome strm->adler = state->wrap & 1; 128*ab9e68a2SToomas Soome state->mode = HEAD; 129*ab9e68a2SToomas Soome state->last = 0; 130*ab9e68a2SToomas Soome state->havedict = 0; 131*ab9e68a2SToomas Soome state->dmax = 32768U; 132*ab9e68a2SToomas Soome state->head = Z_NULL; 133*ab9e68a2SToomas Soome state->hold = 0; 134*ab9e68a2SToomas Soome state->bits = 0; 135*ab9e68a2SToomas Soome state->lencode = state->distcode = state->next = state->codes; 136*ab9e68a2SToomas Soome state->sane = 1; 137*ab9e68a2SToomas Soome state->back = -1; 138*ab9e68a2SToomas Soome Tracev((stderr, "inflate: reset\n")); 139*ab9e68a2SToomas Soome return Z_OK; 140*ab9e68a2SToomas Soome } 141*ab9e68a2SToomas Soome 142*ab9e68a2SToomas Soome int ZEXPORT inflateReset(z_streamp strm) 143*ab9e68a2SToomas Soome { 144*ab9e68a2SToomas Soome struct inflate_state FAR *state; 145*ab9e68a2SToomas Soome 146*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 147*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 148*ab9e68a2SToomas Soome state->wsize = 0; 149*ab9e68a2SToomas Soome state->whave = 0; 150*ab9e68a2SToomas Soome state->wnext = 0; 151*ab9e68a2SToomas Soome return inflateResetKeep(strm); 152*ab9e68a2SToomas Soome } 153*ab9e68a2SToomas Soome 154*ab9e68a2SToomas Soome int ZEXPORT inflateReset2(z_streamp strm, int windowBits) 155*ab9e68a2SToomas Soome { 156*ab9e68a2SToomas Soome int wrap; 157*ab9e68a2SToomas Soome struct inflate_state FAR *state; 158*ab9e68a2SToomas Soome 159*ab9e68a2SToomas Soome /* get the state */ 160*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 161*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 162*ab9e68a2SToomas Soome 163*ab9e68a2SToomas Soome /* extract wrap request from windowBits parameter */ 164*ab9e68a2SToomas Soome if (windowBits < 0) { 165*ab9e68a2SToomas Soome wrap = 0; 166*ab9e68a2SToomas Soome windowBits = -windowBits; 167*ab9e68a2SToomas Soome } 168*ab9e68a2SToomas Soome else { 169*ab9e68a2SToomas Soome wrap = (windowBits >> 4) + 5; 170*ab9e68a2SToomas Soome #ifdef GUNZIP 171*ab9e68a2SToomas Soome if (windowBits < 48) 172*ab9e68a2SToomas Soome windowBits &= 15; 173*ab9e68a2SToomas Soome #endif 174*ab9e68a2SToomas Soome } 175*ab9e68a2SToomas Soome 176*ab9e68a2SToomas Soome /* set number of window bits, free window if different */ 177*ab9e68a2SToomas Soome if (windowBits && (windowBits < 8 || windowBits > 15)) 178*ab9e68a2SToomas Soome return Z_STREAM_ERROR; 179*ab9e68a2SToomas Soome if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { 180*ab9e68a2SToomas Soome ZFREE(strm, state->window); 181*ab9e68a2SToomas Soome state->window = Z_NULL; 182*ab9e68a2SToomas Soome } 183*ab9e68a2SToomas Soome 184*ab9e68a2SToomas Soome /* update state and reset the rest of it */ 185*ab9e68a2SToomas Soome state->wrap = wrap; 186*ab9e68a2SToomas Soome state->wbits = (unsigned)windowBits; 187*ab9e68a2SToomas Soome return inflateReset(strm); 188*ab9e68a2SToomas Soome } 189*ab9e68a2SToomas Soome 190*ab9e68a2SToomas Soome int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, const char *version, 191*ab9e68a2SToomas Soome int stream_size) 192*ab9e68a2SToomas Soome { 193*ab9e68a2SToomas Soome int ret; 194*ab9e68a2SToomas Soome struct inflate_state FAR *state; 195*ab9e68a2SToomas Soome 196*ab9e68a2SToomas Soome if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 197*ab9e68a2SToomas Soome stream_size != (int)(sizeof(z_stream))) 198*ab9e68a2SToomas Soome return Z_VERSION_ERROR; 199*ab9e68a2SToomas Soome if (strm == Z_NULL) return Z_STREAM_ERROR; 200*ab9e68a2SToomas Soome strm->msg = Z_NULL; /* in case we return an error */ 201*ab9e68a2SToomas Soome if (strm->zalloc == (alloc_func)0) { 202*ab9e68a2SToomas Soome #ifdef Z_SOLO 203*ab9e68a2SToomas Soome return Z_STREAM_ERROR; 204*ab9e68a2SToomas Soome #else 205*ab9e68a2SToomas Soome strm->zalloc = zcalloc; 206*ab9e68a2SToomas Soome strm->opaque = (voidpf)0; 207*ab9e68a2SToomas Soome #endif 208*ab9e68a2SToomas Soome } 209*ab9e68a2SToomas Soome if (strm->zfree == (free_func)0) 210*ab9e68a2SToomas Soome #ifdef Z_SOLO 211*ab9e68a2SToomas Soome return Z_STREAM_ERROR; 212*ab9e68a2SToomas Soome #else 213*ab9e68a2SToomas Soome strm->zfree = zcfree; 214*ab9e68a2SToomas Soome #endif 215*ab9e68a2SToomas Soome state = (struct inflate_state FAR *) 216*ab9e68a2SToomas Soome ZALLOC(strm, 1, sizeof(struct inflate_state)); 217*ab9e68a2SToomas Soome if (state == Z_NULL) return Z_MEM_ERROR; 218*ab9e68a2SToomas Soome Tracev((stderr, "inflate: allocated\n")); 219*ab9e68a2SToomas Soome strm->state = (struct internal_state FAR *)state; 220*ab9e68a2SToomas Soome state->strm = strm; 221*ab9e68a2SToomas Soome state->window = Z_NULL; 222*ab9e68a2SToomas Soome state->mode = HEAD; /* to pass state test in inflateReset2() */ 223*ab9e68a2SToomas Soome ret = inflateReset2(strm, windowBits); 224*ab9e68a2SToomas Soome if (ret != Z_OK) { 225*ab9e68a2SToomas Soome ZFREE(strm, state); 226*ab9e68a2SToomas Soome strm->state = Z_NULL; 227*ab9e68a2SToomas Soome } 228*ab9e68a2SToomas Soome return ret; 229*ab9e68a2SToomas Soome } 230*ab9e68a2SToomas Soome 231*ab9e68a2SToomas Soome int ZEXPORT inflateInit_(z_streamp strm, const char *version, int stream_size) 232*ab9e68a2SToomas Soome { 233*ab9e68a2SToomas Soome return inflateInit2_(strm, DEF_WBITS, version, stream_size); 234*ab9e68a2SToomas Soome } 235*ab9e68a2SToomas Soome 236*ab9e68a2SToomas Soome int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) 237*ab9e68a2SToomas Soome { 238*ab9e68a2SToomas Soome struct inflate_state FAR *state; 239*ab9e68a2SToomas Soome 240*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 241*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 242*ab9e68a2SToomas Soome if (bits < 0) { 243*ab9e68a2SToomas Soome state->hold = 0; 244*ab9e68a2SToomas Soome state->bits = 0; 245*ab9e68a2SToomas Soome return Z_OK; 246*ab9e68a2SToomas Soome } 247*ab9e68a2SToomas Soome if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; 248*ab9e68a2SToomas Soome value &= (1L << bits) - 1; 249*ab9e68a2SToomas Soome state->hold += (unsigned)value << state->bits; 250*ab9e68a2SToomas Soome state->bits += (uInt)bits; 251*ab9e68a2SToomas Soome return Z_OK; 252*ab9e68a2SToomas Soome } 253*ab9e68a2SToomas Soome 254*ab9e68a2SToomas Soome /* 255*ab9e68a2SToomas Soome Return state with length and distance decoding tables and index sizes set to 256*ab9e68a2SToomas Soome fixed code decoding. Normally this returns fixed tables from inffixed.h. 257*ab9e68a2SToomas Soome If BUILDFIXED is defined, then instead this routine builds the tables the 258*ab9e68a2SToomas Soome first time it's called, and returns those tables the first time and 259*ab9e68a2SToomas Soome thereafter. This reduces the size of the code by about 2K bytes, in 260*ab9e68a2SToomas Soome exchange for a little execution time. However, BUILDFIXED should not be 261*ab9e68a2SToomas Soome used for threaded applications, since the rewriting of the tables and virgin 262*ab9e68a2SToomas Soome may not be thread-safe. 263*ab9e68a2SToomas Soome */ 264*ab9e68a2SToomas Soome local void fixedtables(struct inflate_state FAR *state) 265*ab9e68a2SToomas Soome { 266*ab9e68a2SToomas Soome #ifdef BUILDFIXED 267*ab9e68a2SToomas Soome static int virgin = 1; 268*ab9e68a2SToomas Soome static code *lenfix, *distfix; 269*ab9e68a2SToomas Soome static code fixed[544]; 270*ab9e68a2SToomas Soome 271*ab9e68a2SToomas Soome /* build fixed huffman tables if first call (may not be thread safe) */ 272*ab9e68a2SToomas Soome if (virgin) { 273*ab9e68a2SToomas Soome unsigned sym, bits; 274*ab9e68a2SToomas Soome static code *next; 275*ab9e68a2SToomas Soome 276*ab9e68a2SToomas Soome /* literal/length table */ 277*ab9e68a2SToomas Soome sym = 0; 278*ab9e68a2SToomas Soome while (sym < 144) state->lens[sym++] = 8; 279*ab9e68a2SToomas Soome while (sym < 256) state->lens[sym++] = 9; 280*ab9e68a2SToomas Soome while (sym < 280) state->lens[sym++] = 7; 281*ab9e68a2SToomas Soome while (sym < 288) state->lens[sym++] = 8; 282*ab9e68a2SToomas Soome next = fixed; 283*ab9e68a2SToomas Soome lenfix = next; 284*ab9e68a2SToomas Soome bits = 9; 285*ab9e68a2SToomas Soome inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); 286*ab9e68a2SToomas Soome 287*ab9e68a2SToomas Soome /* distance table */ 288*ab9e68a2SToomas Soome sym = 0; 289*ab9e68a2SToomas Soome while (sym < 32) state->lens[sym++] = 5; 290*ab9e68a2SToomas Soome distfix = next; 291*ab9e68a2SToomas Soome bits = 5; 292*ab9e68a2SToomas Soome inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); 293*ab9e68a2SToomas Soome 294*ab9e68a2SToomas Soome /* do this just once */ 295*ab9e68a2SToomas Soome virgin = 0; 296*ab9e68a2SToomas Soome } 297*ab9e68a2SToomas Soome #else /* !BUILDFIXED */ 298*ab9e68a2SToomas Soome # include "inffixed.h" 299*ab9e68a2SToomas Soome #endif /* BUILDFIXED */ 300*ab9e68a2SToomas Soome state->lencode = lenfix; 301*ab9e68a2SToomas Soome state->lenbits = 9; 302*ab9e68a2SToomas Soome state->distcode = distfix; 303*ab9e68a2SToomas Soome state->distbits = 5; 304*ab9e68a2SToomas Soome } 305*ab9e68a2SToomas Soome 306*ab9e68a2SToomas Soome #ifdef MAKEFIXED 307*ab9e68a2SToomas Soome #include <stdio.h> 308*ab9e68a2SToomas Soome 309*ab9e68a2SToomas Soome /* 310*ab9e68a2SToomas Soome Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also 311*ab9e68a2SToomas Soome defines BUILDFIXED, so the tables are built on the fly. makefixed() writes 312*ab9e68a2SToomas Soome those tables to stdout, which would be piped to inffixed.h. A small program 313*ab9e68a2SToomas Soome can simply call makefixed to do this: 314*ab9e68a2SToomas Soome 315*ab9e68a2SToomas Soome void makefixed(void); 316*ab9e68a2SToomas Soome 317*ab9e68a2SToomas Soome int main(void) 318*ab9e68a2SToomas Soome { 319*ab9e68a2SToomas Soome makefixed(); 320*ab9e68a2SToomas Soome return 0; 321*ab9e68a2SToomas Soome } 322*ab9e68a2SToomas Soome 323*ab9e68a2SToomas Soome Then that can be linked with zlib built with MAKEFIXED defined and run: 324*ab9e68a2SToomas Soome 325*ab9e68a2SToomas Soome a.out > inffixed.h 326*ab9e68a2SToomas Soome */ 327*ab9e68a2SToomas Soome void makefixed(void) 328*ab9e68a2SToomas Soome { 329*ab9e68a2SToomas Soome unsigned low, size; 330*ab9e68a2SToomas Soome struct inflate_state state; 331*ab9e68a2SToomas Soome 332*ab9e68a2SToomas Soome fixedtables(&state); 333*ab9e68a2SToomas Soome puts(" /* inffixed.h -- table for decoding fixed codes"); 334*ab9e68a2SToomas Soome puts(" * Generated automatically by makefixed()."); 335*ab9e68a2SToomas Soome puts(" */"); 336*ab9e68a2SToomas Soome puts(""); 337*ab9e68a2SToomas Soome puts(" /* WARNING: this file should *not* be used by applications."); 338*ab9e68a2SToomas Soome puts(" It is part of the implementation of this library and is"); 339*ab9e68a2SToomas Soome puts(" subject to change. Applications should only use zlib.h."); 340*ab9e68a2SToomas Soome puts(" */"); 341*ab9e68a2SToomas Soome puts(""); 342*ab9e68a2SToomas Soome size = 1U << 9; 343*ab9e68a2SToomas Soome printf(" static const code lenfix[%u] = {", size); 344*ab9e68a2SToomas Soome low = 0; 345*ab9e68a2SToomas Soome for (;;) { 346*ab9e68a2SToomas Soome if ((low % 7) == 0) printf("\n "); 347*ab9e68a2SToomas Soome printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, 348*ab9e68a2SToomas Soome state.lencode[low].bits, state.lencode[low].val); 349*ab9e68a2SToomas Soome if (++low == size) break; 350*ab9e68a2SToomas Soome putchar(','); 351*ab9e68a2SToomas Soome } 352*ab9e68a2SToomas Soome puts("\n };"); 353*ab9e68a2SToomas Soome size = 1U << 5; 354*ab9e68a2SToomas Soome printf("\n static const code distfix[%u] = {", size); 355*ab9e68a2SToomas Soome low = 0; 356*ab9e68a2SToomas Soome for (;;) { 357*ab9e68a2SToomas Soome if ((low % 6) == 0) printf("\n "); 358*ab9e68a2SToomas Soome printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, 359*ab9e68a2SToomas Soome state.distcode[low].val); 360*ab9e68a2SToomas Soome if (++low == size) break; 361*ab9e68a2SToomas Soome putchar(','); 362*ab9e68a2SToomas Soome } 363*ab9e68a2SToomas Soome puts("\n };"); 364*ab9e68a2SToomas Soome } 365*ab9e68a2SToomas Soome #endif /* MAKEFIXED */ 366*ab9e68a2SToomas Soome 367*ab9e68a2SToomas Soome /* 368*ab9e68a2SToomas Soome Update the window with the last wsize (normally 32K) bytes written before 369*ab9e68a2SToomas Soome returning. If window does not exist yet, create it. This is only called 370*ab9e68a2SToomas Soome when a window is already in use, or when output has been written during this 371*ab9e68a2SToomas Soome inflate call, but the end of the deflate stream has not been reached yet. 372*ab9e68a2SToomas Soome It is also called to create a window for dictionary data when a dictionary 373*ab9e68a2SToomas Soome is loaded. 374*ab9e68a2SToomas Soome 375*ab9e68a2SToomas Soome Providing output buffers larger than 32K to inflate() should provide a speed 376*ab9e68a2SToomas Soome advantage, since only the last 32K of output is copied to the sliding window 377*ab9e68a2SToomas Soome upon return from inflate(), and since all distances after the first 32K of 378*ab9e68a2SToomas Soome output will fall in the output data, making match copies simpler and faster. 379*ab9e68a2SToomas Soome The advantage may be dependent on the size of the processor's data caches. 380*ab9e68a2SToomas Soome */ 381*ab9e68a2SToomas Soome local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) 382*ab9e68a2SToomas Soome { 383*ab9e68a2SToomas Soome struct inflate_state FAR *state; 384*ab9e68a2SToomas Soome unsigned dist; 385*ab9e68a2SToomas Soome 386*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 387*ab9e68a2SToomas Soome 388*ab9e68a2SToomas Soome /* if it hasn't been done already, allocate space for the window */ 389*ab9e68a2SToomas Soome if (state->window == Z_NULL) { 390*ab9e68a2SToomas Soome state->window = (unsigned char FAR *) 391*ab9e68a2SToomas Soome ZALLOC(strm, 1U << state->wbits, 392*ab9e68a2SToomas Soome sizeof(unsigned char)); 393*ab9e68a2SToomas Soome if (state->window == Z_NULL) return 1; 394*ab9e68a2SToomas Soome } 395*ab9e68a2SToomas Soome 396*ab9e68a2SToomas Soome /* if window not in use yet, initialize */ 397*ab9e68a2SToomas Soome if (state->wsize == 0) { 398*ab9e68a2SToomas Soome state->wsize = 1U << state->wbits; 399*ab9e68a2SToomas Soome state->wnext = 0; 400*ab9e68a2SToomas Soome state->whave = 0; 401*ab9e68a2SToomas Soome } 402*ab9e68a2SToomas Soome 403*ab9e68a2SToomas Soome /* copy state->wsize or less output bytes into the circular window */ 404*ab9e68a2SToomas Soome if (copy >= state->wsize) { 405*ab9e68a2SToomas Soome zmemcpy(state->window, end - state->wsize, state->wsize); 406*ab9e68a2SToomas Soome state->wnext = 0; 407*ab9e68a2SToomas Soome state->whave = state->wsize; 408*ab9e68a2SToomas Soome } 409*ab9e68a2SToomas Soome else { 410*ab9e68a2SToomas Soome dist = state->wsize - state->wnext; 411*ab9e68a2SToomas Soome if (dist > copy) dist = copy; 412*ab9e68a2SToomas Soome zmemcpy(state->window + state->wnext, end - copy, dist); 413*ab9e68a2SToomas Soome copy -= dist; 414*ab9e68a2SToomas Soome if (copy) { 415*ab9e68a2SToomas Soome zmemcpy(state->window, end - copy, copy); 416*ab9e68a2SToomas Soome state->wnext = copy; 417*ab9e68a2SToomas Soome state->whave = state->wsize; 418*ab9e68a2SToomas Soome } 419*ab9e68a2SToomas Soome else { 420*ab9e68a2SToomas Soome state->wnext += dist; 421*ab9e68a2SToomas Soome if (state->wnext == state->wsize) state->wnext = 0; 422*ab9e68a2SToomas Soome if (state->whave < state->wsize) state->whave += dist; 423*ab9e68a2SToomas Soome } 424*ab9e68a2SToomas Soome } 425*ab9e68a2SToomas Soome return 0; 426*ab9e68a2SToomas Soome } 427*ab9e68a2SToomas Soome 428*ab9e68a2SToomas Soome /* Macros for inflate(): */ 429*ab9e68a2SToomas Soome 430*ab9e68a2SToomas Soome /* check function to use adler32() for zlib or crc32() for gzip */ 431*ab9e68a2SToomas Soome #ifdef GUNZIP 432*ab9e68a2SToomas Soome # define UPDATE(check, buf, len) \ 433*ab9e68a2SToomas Soome (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) 434*ab9e68a2SToomas Soome #else 435*ab9e68a2SToomas Soome # define UPDATE(check, buf, len) adler32(check, buf, len) 436*ab9e68a2SToomas Soome #endif 437*ab9e68a2SToomas Soome 438*ab9e68a2SToomas Soome /* check macros for header crc */ 439*ab9e68a2SToomas Soome #ifdef GUNZIP 440*ab9e68a2SToomas Soome # define CRC2(check, word) \ 441*ab9e68a2SToomas Soome do { \ 442*ab9e68a2SToomas Soome hbuf[0] = (unsigned char)(word); \ 443*ab9e68a2SToomas Soome hbuf[1] = (unsigned char)((word) >> 8); \ 444*ab9e68a2SToomas Soome check = crc32(check, hbuf, 2); \ 445*ab9e68a2SToomas Soome } while (0) 446*ab9e68a2SToomas Soome 447*ab9e68a2SToomas Soome # define CRC4(check, word) \ 448*ab9e68a2SToomas Soome do { \ 449*ab9e68a2SToomas Soome hbuf[0] = (unsigned char)(word); \ 450*ab9e68a2SToomas Soome hbuf[1] = (unsigned char)((word) >> 8); \ 451*ab9e68a2SToomas Soome hbuf[2] = (unsigned char)((word) >> 16); \ 452*ab9e68a2SToomas Soome hbuf[3] = (unsigned char)((word) >> 24); \ 453*ab9e68a2SToomas Soome check = crc32(check, hbuf, 4); \ 454*ab9e68a2SToomas Soome } while (0) 455*ab9e68a2SToomas Soome #endif 456*ab9e68a2SToomas Soome 457*ab9e68a2SToomas Soome /* Load registers with state in inflate() for speed */ 458*ab9e68a2SToomas Soome #define LOAD() \ 459*ab9e68a2SToomas Soome do { \ 460*ab9e68a2SToomas Soome put = strm->next_out; \ 461*ab9e68a2SToomas Soome left = strm->avail_out; \ 462*ab9e68a2SToomas Soome next = strm->next_in; \ 463*ab9e68a2SToomas Soome have = strm->avail_in; \ 464*ab9e68a2SToomas Soome hold = state->hold; \ 465*ab9e68a2SToomas Soome bits = state->bits; \ 466*ab9e68a2SToomas Soome } while (0) 467*ab9e68a2SToomas Soome 468*ab9e68a2SToomas Soome /* Restore state from registers in inflate() */ 469*ab9e68a2SToomas Soome #define RESTORE() \ 470*ab9e68a2SToomas Soome do { \ 471*ab9e68a2SToomas Soome strm->next_out = put; \ 472*ab9e68a2SToomas Soome strm->avail_out = left; \ 473*ab9e68a2SToomas Soome strm->next_in = next; \ 474*ab9e68a2SToomas Soome strm->avail_in = have; \ 475*ab9e68a2SToomas Soome state->hold = hold; \ 476*ab9e68a2SToomas Soome state->bits = bits; \ 477*ab9e68a2SToomas Soome } while (0) 478*ab9e68a2SToomas Soome 479*ab9e68a2SToomas Soome /* Clear the input bit accumulator */ 480*ab9e68a2SToomas Soome #define INITBITS() \ 481*ab9e68a2SToomas Soome do { \ 482*ab9e68a2SToomas Soome hold = 0; \ 483*ab9e68a2SToomas Soome bits = 0; \ 484*ab9e68a2SToomas Soome } while (0) 485*ab9e68a2SToomas Soome 486*ab9e68a2SToomas Soome /* Get a byte of input into the bit accumulator, or return from inflate() 487*ab9e68a2SToomas Soome if there is no input available. */ 488*ab9e68a2SToomas Soome #define PULLBYTE() \ 489*ab9e68a2SToomas Soome do { \ 490*ab9e68a2SToomas Soome if (have == 0) goto inf_leave; \ 491*ab9e68a2SToomas Soome have--; \ 492*ab9e68a2SToomas Soome hold += (unsigned long)(*next++) << bits; \ 493*ab9e68a2SToomas Soome bits += 8; \ 494*ab9e68a2SToomas Soome } while (0) 495*ab9e68a2SToomas Soome 496*ab9e68a2SToomas Soome /* Assure that there are at least n bits in the bit accumulator. If there is 497*ab9e68a2SToomas Soome not enough available input to do that, then return from inflate(). */ 498*ab9e68a2SToomas Soome #define NEEDBITS(n) \ 499*ab9e68a2SToomas Soome do { \ 500*ab9e68a2SToomas Soome while (bits < (unsigned)(n)) \ 501*ab9e68a2SToomas Soome PULLBYTE(); \ 502*ab9e68a2SToomas Soome } while (0) 503*ab9e68a2SToomas Soome 504*ab9e68a2SToomas Soome /* Return the low n bits of the bit accumulator (n < 16) */ 505*ab9e68a2SToomas Soome #define BITS(n) \ 506*ab9e68a2SToomas Soome ((unsigned)hold & ((1U << (n)) - 1)) 507*ab9e68a2SToomas Soome 508*ab9e68a2SToomas Soome /* Remove n bits from the bit accumulator */ 509*ab9e68a2SToomas Soome #define DROPBITS(n) \ 510*ab9e68a2SToomas Soome do { \ 511*ab9e68a2SToomas Soome hold >>= (n); \ 512*ab9e68a2SToomas Soome bits -= (unsigned)(n); \ 513*ab9e68a2SToomas Soome } while (0) 514*ab9e68a2SToomas Soome 515*ab9e68a2SToomas Soome /* Remove zero to seven bits as needed to go to a byte boundary */ 516*ab9e68a2SToomas Soome #define BYTEBITS() \ 517*ab9e68a2SToomas Soome do { \ 518*ab9e68a2SToomas Soome hold >>= bits & 7; \ 519*ab9e68a2SToomas Soome bits -= bits & 7; \ 520*ab9e68a2SToomas Soome } while (0) 521*ab9e68a2SToomas Soome 522*ab9e68a2SToomas Soome /* 523*ab9e68a2SToomas Soome inflate() uses a state machine to process as much input data and generate as 524*ab9e68a2SToomas Soome much output data as possible before returning. The state machine is 525*ab9e68a2SToomas Soome structured roughly as follows: 526*ab9e68a2SToomas Soome 527*ab9e68a2SToomas Soome for (;;) switch (state) { 528*ab9e68a2SToomas Soome ... 529*ab9e68a2SToomas Soome case STATEn: 530*ab9e68a2SToomas Soome if (not enough input data or output space to make progress) 531*ab9e68a2SToomas Soome return; 532*ab9e68a2SToomas Soome ... make progress ... 533*ab9e68a2SToomas Soome state = STATEm; 534*ab9e68a2SToomas Soome break; 535*ab9e68a2SToomas Soome ... 536*ab9e68a2SToomas Soome } 537*ab9e68a2SToomas Soome 538*ab9e68a2SToomas Soome so when inflate() is called again, the same case is attempted again, and 539*ab9e68a2SToomas Soome if the appropriate resources are provided, the machine proceeds to the 540*ab9e68a2SToomas Soome next state. The NEEDBITS() macro is usually the way the state evaluates 541*ab9e68a2SToomas Soome whether it can proceed or should return. NEEDBITS() does the return if 542*ab9e68a2SToomas Soome the requested bits are not available. The typical use of the BITS macros 543*ab9e68a2SToomas Soome is: 544*ab9e68a2SToomas Soome 545*ab9e68a2SToomas Soome NEEDBITS(n); 546*ab9e68a2SToomas Soome ... do something with BITS(n) ... 547*ab9e68a2SToomas Soome DROPBITS(n); 548*ab9e68a2SToomas Soome 549*ab9e68a2SToomas Soome where NEEDBITS(n) either returns from inflate() if there isn't enough 550*ab9e68a2SToomas Soome input left to load n bits into the accumulator, or it continues. BITS(n) 551*ab9e68a2SToomas Soome gives the low n bits in the accumulator. When done, DROPBITS(n) drops 552*ab9e68a2SToomas Soome the low n bits off the accumulator. INITBITS() clears the accumulator 553*ab9e68a2SToomas Soome and sets the number of available bits to zero. BYTEBITS() discards just 554*ab9e68a2SToomas Soome enough bits to put the accumulator on a byte boundary. After BYTEBITS() 555*ab9e68a2SToomas Soome and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. 556*ab9e68a2SToomas Soome 557*ab9e68a2SToomas Soome NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return 558*ab9e68a2SToomas Soome if there is no input available. The decoding of variable length codes uses 559*ab9e68a2SToomas Soome PULLBYTE() directly in order to pull just enough bytes to decode the next 560*ab9e68a2SToomas Soome code, and no more. 561*ab9e68a2SToomas Soome 562*ab9e68a2SToomas Soome Some states loop until they get enough input, making sure that enough 563*ab9e68a2SToomas Soome state information is maintained to continue the loop where it left off 564*ab9e68a2SToomas Soome if NEEDBITS() returns in the loop. For example, want, need, and keep 565*ab9e68a2SToomas Soome would all have to actually be part of the saved state in case NEEDBITS() 566*ab9e68a2SToomas Soome returns: 567*ab9e68a2SToomas Soome 568*ab9e68a2SToomas Soome case STATEw: 569*ab9e68a2SToomas Soome while (want < need) { 570*ab9e68a2SToomas Soome NEEDBITS(n); 571*ab9e68a2SToomas Soome keep[want++] = BITS(n); 572*ab9e68a2SToomas Soome DROPBITS(n); 573*ab9e68a2SToomas Soome } 574*ab9e68a2SToomas Soome state = STATEx; 575*ab9e68a2SToomas Soome case STATEx: 576*ab9e68a2SToomas Soome 577*ab9e68a2SToomas Soome As shown above, if the next state is also the next case, then the break 578*ab9e68a2SToomas Soome is omitted. 579*ab9e68a2SToomas Soome 580*ab9e68a2SToomas Soome A state may also return if there is not enough output space available to 581*ab9e68a2SToomas Soome complete that state. Those states are copying stored data, writing a 582*ab9e68a2SToomas Soome literal byte, and copying a matching string. 583*ab9e68a2SToomas Soome 584*ab9e68a2SToomas Soome When returning, a "goto inf_leave" is used to update the total counters, 585*ab9e68a2SToomas Soome update the check value, and determine whether any progress has been made 586*ab9e68a2SToomas Soome during that inflate() call in order to return the proper return code. 587*ab9e68a2SToomas Soome Progress is defined as a change in either strm->avail_in or strm->avail_out. 588*ab9e68a2SToomas Soome When there is a window, goto inf_leave will update the window with the last 589*ab9e68a2SToomas Soome output written. If a goto inf_leave occurs in the middle of decompression 590*ab9e68a2SToomas Soome and there is no window currently, goto inf_leave will create one and copy 591*ab9e68a2SToomas Soome output to the window for the next call of inflate(). 592*ab9e68a2SToomas Soome 593*ab9e68a2SToomas Soome In this implementation, the flush parameter of inflate() only affects the 594*ab9e68a2SToomas Soome return code (per zlib.h). inflate() always writes as much as possible to 595*ab9e68a2SToomas Soome strm->next_out, given the space available and the provided input--the effect 596*ab9e68a2SToomas Soome documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers 597*ab9e68a2SToomas Soome the allocation of and copying into a sliding window until necessary, which 598*ab9e68a2SToomas Soome provides the effect documented in zlib.h for Z_FINISH when the entire input 599*ab9e68a2SToomas Soome stream available. So the only thing the flush parameter actually does is: 600*ab9e68a2SToomas Soome when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it 601*ab9e68a2SToomas Soome will return Z_BUF_ERROR if it has not reached the end of the stream. 602*ab9e68a2SToomas Soome */ 603*ab9e68a2SToomas Soome 604*ab9e68a2SToomas Soome int ZEXPORT inflate(z_streamp strm, int flush) 605*ab9e68a2SToomas Soome { 606*ab9e68a2SToomas Soome struct inflate_state FAR *state; 607*ab9e68a2SToomas Soome z_const unsigned char FAR *next; /* next input */ 608*ab9e68a2SToomas Soome unsigned char FAR *put; /* next output */ 609*ab9e68a2SToomas Soome unsigned have, left; /* available input and output */ 610*ab9e68a2SToomas Soome unsigned long hold; /* bit buffer */ 611*ab9e68a2SToomas Soome unsigned bits; /* bits in bit buffer */ 612*ab9e68a2SToomas Soome unsigned in, out; /* save starting available input and output */ 613*ab9e68a2SToomas Soome unsigned copy; /* number of stored or match bytes to copy */ 614*ab9e68a2SToomas Soome unsigned char FAR *from; /* where to copy match bytes from */ 615*ab9e68a2SToomas Soome code here; /* current decoding table entry */ 616*ab9e68a2SToomas Soome code last; /* parent table entry */ 617*ab9e68a2SToomas Soome unsigned len; /* length to copy for repeats, bits to drop */ 618*ab9e68a2SToomas Soome int ret; /* return code */ 619*ab9e68a2SToomas Soome #ifdef GUNZIP 620*ab9e68a2SToomas Soome unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ 621*ab9e68a2SToomas Soome #endif 622*ab9e68a2SToomas Soome static const unsigned short order[19] = /* permutation of code lengths */ 623*ab9e68a2SToomas Soome {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 624*ab9e68a2SToomas Soome 625*ab9e68a2SToomas Soome if (inflateStateCheck(strm) || strm->next_out == Z_NULL || 626*ab9e68a2SToomas Soome (strm->next_in == Z_NULL && strm->avail_in != 0)) 627*ab9e68a2SToomas Soome return Z_STREAM_ERROR; 628*ab9e68a2SToomas Soome 629*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 630*ab9e68a2SToomas Soome if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ 631*ab9e68a2SToomas Soome LOAD(); 632*ab9e68a2SToomas Soome in = have; 633*ab9e68a2SToomas Soome out = left; 634*ab9e68a2SToomas Soome ret = Z_OK; 635*ab9e68a2SToomas Soome for (;;) 636*ab9e68a2SToomas Soome switch (state->mode) { 637*ab9e68a2SToomas Soome case HEAD: 638*ab9e68a2SToomas Soome if (state->wrap == 0) { 639*ab9e68a2SToomas Soome state->mode = TYPEDO; 640*ab9e68a2SToomas Soome break; 641*ab9e68a2SToomas Soome } 642*ab9e68a2SToomas Soome NEEDBITS(16); 643*ab9e68a2SToomas Soome #ifdef GUNZIP 644*ab9e68a2SToomas Soome if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ 645*ab9e68a2SToomas Soome if (state->wbits == 0) 646*ab9e68a2SToomas Soome state->wbits = 15; 647*ab9e68a2SToomas Soome state->check = crc32(0L, Z_NULL, 0); 648*ab9e68a2SToomas Soome CRC2(state->check, hold); 649*ab9e68a2SToomas Soome INITBITS(); 650*ab9e68a2SToomas Soome state->mode = FLAGS; 651*ab9e68a2SToomas Soome break; 652*ab9e68a2SToomas Soome } 653*ab9e68a2SToomas Soome state->flags = 0; /* expect zlib header */ 654*ab9e68a2SToomas Soome if (state->head != Z_NULL) 655*ab9e68a2SToomas Soome state->head->done = -1; 656*ab9e68a2SToomas Soome if (!(state->wrap & 1) || /* check if zlib header allowed */ 657*ab9e68a2SToomas Soome #else 658*ab9e68a2SToomas Soome if ( 659*ab9e68a2SToomas Soome #endif 660*ab9e68a2SToomas Soome ((BITS(8) << 8) + (hold >> 8)) % 31) { 661*ab9e68a2SToomas Soome strm->msg = (char *)"incorrect header check"; 662*ab9e68a2SToomas Soome state->mode = BAD; 663*ab9e68a2SToomas Soome break; 664*ab9e68a2SToomas Soome } 665*ab9e68a2SToomas Soome if (BITS(4) != Z_DEFLATED) { 666*ab9e68a2SToomas Soome strm->msg = (char *)"unknown compression method"; 667*ab9e68a2SToomas Soome state->mode = BAD; 668*ab9e68a2SToomas Soome break; 669*ab9e68a2SToomas Soome } 670*ab9e68a2SToomas Soome DROPBITS(4); 671*ab9e68a2SToomas Soome len = BITS(4) + 8; 672*ab9e68a2SToomas Soome if (state->wbits == 0) 673*ab9e68a2SToomas Soome state->wbits = len; 674*ab9e68a2SToomas Soome if (len > 15 || len > state->wbits) { 675*ab9e68a2SToomas Soome strm->msg = (char *)"invalid window size"; 676*ab9e68a2SToomas Soome state->mode = BAD; 677*ab9e68a2SToomas Soome break; 678*ab9e68a2SToomas Soome } 679*ab9e68a2SToomas Soome state->dmax = 1U << len; 680*ab9e68a2SToomas Soome Tracev((stderr, "inflate: zlib header ok\n")); 681*ab9e68a2SToomas Soome strm->adler = state->check = adler32(0L, Z_NULL, 0); 682*ab9e68a2SToomas Soome state->mode = hold & 0x200 ? DICTID : TYPE; 683*ab9e68a2SToomas Soome INITBITS(); 684*ab9e68a2SToomas Soome break; 685*ab9e68a2SToomas Soome #ifdef GUNZIP 686*ab9e68a2SToomas Soome case FLAGS: 687*ab9e68a2SToomas Soome NEEDBITS(16); 688*ab9e68a2SToomas Soome state->flags = (int)(hold); 689*ab9e68a2SToomas Soome if ((state->flags & 0xff) != Z_DEFLATED) { 690*ab9e68a2SToomas Soome strm->msg = (char *)"unknown compression method"; 691*ab9e68a2SToomas Soome state->mode = BAD; 692*ab9e68a2SToomas Soome break; 693*ab9e68a2SToomas Soome } 694*ab9e68a2SToomas Soome if (state->flags & 0xe000) { 695*ab9e68a2SToomas Soome strm->msg = (char *)"unknown header flags set"; 696*ab9e68a2SToomas Soome state->mode = BAD; 697*ab9e68a2SToomas Soome break; 698*ab9e68a2SToomas Soome } 699*ab9e68a2SToomas Soome if (state->head != Z_NULL) 700*ab9e68a2SToomas Soome state->head->text = (int)((hold >> 8) & 1); 701*ab9e68a2SToomas Soome if ((state->flags & 0x0200) && (state->wrap & 4)) 702*ab9e68a2SToomas Soome CRC2(state->check, hold); 703*ab9e68a2SToomas Soome INITBITS(); 704*ab9e68a2SToomas Soome state->mode = TIME; 705*ab9e68a2SToomas Soome case TIME: 706*ab9e68a2SToomas Soome NEEDBITS(32); 707*ab9e68a2SToomas Soome if (state->head != Z_NULL) 708*ab9e68a2SToomas Soome state->head->time = hold; 709*ab9e68a2SToomas Soome if ((state->flags & 0x0200) && (state->wrap & 4)) 710*ab9e68a2SToomas Soome CRC4(state->check, hold); 711*ab9e68a2SToomas Soome INITBITS(); 712*ab9e68a2SToomas Soome state->mode = OS; 713*ab9e68a2SToomas Soome case OS: 714*ab9e68a2SToomas Soome NEEDBITS(16); 715*ab9e68a2SToomas Soome if (state->head != Z_NULL) { 716*ab9e68a2SToomas Soome state->head->xflags = (int)(hold & 0xff); 717*ab9e68a2SToomas Soome state->head->os = (int)(hold >> 8); 718*ab9e68a2SToomas Soome } 719*ab9e68a2SToomas Soome if ((state->flags & 0x0200) && (state->wrap & 4)) 720*ab9e68a2SToomas Soome CRC2(state->check, hold); 721*ab9e68a2SToomas Soome INITBITS(); 722*ab9e68a2SToomas Soome state->mode = EXLEN; 723*ab9e68a2SToomas Soome /* FALLTHROUGH */ 724*ab9e68a2SToomas Soome case EXLEN: 725*ab9e68a2SToomas Soome if (state->flags & 0x0400) { 726*ab9e68a2SToomas Soome NEEDBITS(16); 727*ab9e68a2SToomas Soome state->length = (unsigned)(hold); 728*ab9e68a2SToomas Soome if (state->head != Z_NULL) 729*ab9e68a2SToomas Soome state->head->extra_len = (unsigned)hold; 730*ab9e68a2SToomas Soome if ((state->flags & 0x0200) && (state->wrap & 4)) 731*ab9e68a2SToomas Soome CRC2(state->check, hold); 732*ab9e68a2SToomas Soome INITBITS(); 733*ab9e68a2SToomas Soome } 734*ab9e68a2SToomas Soome else if (state->head != Z_NULL) 735*ab9e68a2SToomas Soome state->head->extra = Z_NULL; 736*ab9e68a2SToomas Soome state->mode = EXTRA; 737*ab9e68a2SToomas Soome /* FALLTHROUGH */ 738*ab9e68a2SToomas Soome case EXTRA: 739*ab9e68a2SToomas Soome if (state->flags & 0x0400) { 740*ab9e68a2SToomas Soome copy = state->length; 741*ab9e68a2SToomas Soome if (copy > have) copy = have; 742*ab9e68a2SToomas Soome if (copy) { 743*ab9e68a2SToomas Soome if (state->head != Z_NULL && 744*ab9e68a2SToomas Soome state->head->extra != Z_NULL) { 745*ab9e68a2SToomas Soome len = state->head->extra_len - state->length; 746*ab9e68a2SToomas Soome zmemcpy(state->head->extra + len, next, 747*ab9e68a2SToomas Soome len + copy > state->head->extra_max ? 748*ab9e68a2SToomas Soome state->head->extra_max - len : copy); 749*ab9e68a2SToomas Soome } 750*ab9e68a2SToomas Soome if ((state->flags & 0x0200) && (state->wrap & 4)) 751*ab9e68a2SToomas Soome state->check = crc32(state->check, next, copy); 752*ab9e68a2SToomas Soome have -= copy; 753*ab9e68a2SToomas Soome next += copy; 754*ab9e68a2SToomas Soome state->length -= copy; 755*ab9e68a2SToomas Soome } 756*ab9e68a2SToomas Soome if (state->length) goto inf_leave; 757*ab9e68a2SToomas Soome } 758*ab9e68a2SToomas Soome state->length = 0; 759*ab9e68a2SToomas Soome state->mode = NAME; 760*ab9e68a2SToomas Soome /* FALLTHROUGH */ 761*ab9e68a2SToomas Soome case NAME: 762*ab9e68a2SToomas Soome if (state->flags & 0x0800) { 763*ab9e68a2SToomas Soome if (have == 0) goto inf_leave; 764*ab9e68a2SToomas Soome copy = 0; 765*ab9e68a2SToomas Soome do { 766*ab9e68a2SToomas Soome len = (unsigned)(next[copy++]); 767*ab9e68a2SToomas Soome if (state->head != Z_NULL && 768*ab9e68a2SToomas Soome state->head->name != Z_NULL && 769*ab9e68a2SToomas Soome state->length < state->head->name_max) 770*ab9e68a2SToomas Soome state->head->name[state->length++] = (Bytef)len; 771*ab9e68a2SToomas Soome } while (len && copy < have); 772*ab9e68a2SToomas Soome if ((state->flags & 0x0200) && (state->wrap & 4)) 773*ab9e68a2SToomas Soome state->check = crc32(state->check, next, copy); 774*ab9e68a2SToomas Soome have -= copy; 775*ab9e68a2SToomas Soome next += copy; 776*ab9e68a2SToomas Soome if (len) goto inf_leave; 777*ab9e68a2SToomas Soome } 778*ab9e68a2SToomas Soome else if (state->head != Z_NULL) 779*ab9e68a2SToomas Soome state->head->name = Z_NULL; 780*ab9e68a2SToomas Soome state->length = 0; 781*ab9e68a2SToomas Soome state->mode = COMMENT; 782*ab9e68a2SToomas Soome /* FALLTHROUGH */ 783*ab9e68a2SToomas Soome case COMMENT: 784*ab9e68a2SToomas Soome if (state->flags & 0x1000) { 785*ab9e68a2SToomas Soome if (have == 0) goto inf_leave; 786*ab9e68a2SToomas Soome copy = 0; 787*ab9e68a2SToomas Soome do { 788*ab9e68a2SToomas Soome len = (unsigned)(next[copy++]); 789*ab9e68a2SToomas Soome if (state->head != Z_NULL && 790*ab9e68a2SToomas Soome state->head->comment != Z_NULL && 791*ab9e68a2SToomas Soome state->length < state->head->comm_max) 792*ab9e68a2SToomas Soome state->head->comment[state->length++] = (Bytef)len; 793*ab9e68a2SToomas Soome } while (len && copy < have); 794*ab9e68a2SToomas Soome if ((state->flags & 0x0200) && (state->wrap & 4)) 795*ab9e68a2SToomas Soome state->check = crc32(state->check, next, copy); 796*ab9e68a2SToomas Soome have -= copy; 797*ab9e68a2SToomas Soome next += copy; 798*ab9e68a2SToomas Soome if (len) goto inf_leave; 799*ab9e68a2SToomas Soome } 800*ab9e68a2SToomas Soome else if (state->head != Z_NULL) 801*ab9e68a2SToomas Soome state->head->comment = Z_NULL; 802*ab9e68a2SToomas Soome state->mode = HCRC; 803*ab9e68a2SToomas Soome /* FALLTHROUGH */ 804*ab9e68a2SToomas Soome case HCRC: 805*ab9e68a2SToomas Soome if (state->flags & 0x0200) { 806*ab9e68a2SToomas Soome NEEDBITS(16); 807*ab9e68a2SToomas Soome if ((state->wrap & 4) && hold != (state->check & 0xffff)) { 808*ab9e68a2SToomas Soome strm->msg = (char *)"header crc mismatch"; 809*ab9e68a2SToomas Soome state->mode = BAD; 810*ab9e68a2SToomas Soome break; 811*ab9e68a2SToomas Soome } 812*ab9e68a2SToomas Soome INITBITS(); 813*ab9e68a2SToomas Soome } 814*ab9e68a2SToomas Soome if (state->head != Z_NULL) { 815*ab9e68a2SToomas Soome state->head->hcrc = (int)((state->flags >> 9) & 1); 816*ab9e68a2SToomas Soome state->head->done = 1; 817*ab9e68a2SToomas Soome } 818*ab9e68a2SToomas Soome strm->adler = state->check = crc32(0L, Z_NULL, 0); 819*ab9e68a2SToomas Soome state->mode = TYPE; 820*ab9e68a2SToomas Soome break; 821*ab9e68a2SToomas Soome #endif 822*ab9e68a2SToomas Soome case DICTID: 823*ab9e68a2SToomas Soome NEEDBITS(32); 824*ab9e68a2SToomas Soome strm->adler = state->check = ZSWAP32(hold); 825*ab9e68a2SToomas Soome INITBITS(); 826*ab9e68a2SToomas Soome state->mode = DICT; 827*ab9e68a2SToomas Soome /* FALLTHROUGH */ 828*ab9e68a2SToomas Soome case DICT: 829*ab9e68a2SToomas Soome if (state->havedict == 0) { 830*ab9e68a2SToomas Soome RESTORE(); 831*ab9e68a2SToomas Soome return Z_NEED_DICT; 832*ab9e68a2SToomas Soome } 833*ab9e68a2SToomas Soome strm->adler = state->check = adler32(0L, Z_NULL, 0); 834*ab9e68a2SToomas Soome state->mode = TYPE; 835*ab9e68a2SToomas Soome /* FALLTHROUGH */ 836*ab9e68a2SToomas Soome case TYPE: 837*ab9e68a2SToomas Soome if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; 838*ab9e68a2SToomas Soome /* FALLTHROUGH */ 839*ab9e68a2SToomas Soome case TYPEDO: 840*ab9e68a2SToomas Soome if (state->last) { 841*ab9e68a2SToomas Soome BYTEBITS(); 842*ab9e68a2SToomas Soome state->mode = CHECK; 843*ab9e68a2SToomas Soome break; 844*ab9e68a2SToomas Soome } 845*ab9e68a2SToomas Soome NEEDBITS(3); 846*ab9e68a2SToomas Soome state->last = BITS(1); 847*ab9e68a2SToomas Soome DROPBITS(1); 848*ab9e68a2SToomas Soome switch (BITS(2)) { 849*ab9e68a2SToomas Soome case 0: /* stored block */ 850*ab9e68a2SToomas Soome Tracev((stderr, "inflate: stored block%s\n", 851*ab9e68a2SToomas Soome state->last ? " (last)" : "")); 852*ab9e68a2SToomas Soome state->mode = STORED; 853*ab9e68a2SToomas Soome break; 854*ab9e68a2SToomas Soome case 1: /* fixed block */ 855*ab9e68a2SToomas Soome fixedtables(state); 856*ab9e68a2SToomas Soome Tracev((stderr, "inflate: fixed codes block%s\n", 857*ab9e68a2SToomas Soome state->last ? " (last)" : "")); 858*ab9e68a2SToomas Soome state->mode = LEN_; /* decode codes */ 859*ab9e68a2SToomas Soome if (flush == Z_TREES) { 860*ab9e68a2SToomas Soome DROPBITS(2); 861*ab9e68a2SToomas Soome goto inf_leave; 862*ab9e68a2SToomas Soome } 863*ab9e68a2SToomas Soome break; 864*ab9e68a2SToomas Soome case 2: /* dynamic block */ 865*ab9e68a2SToomas Soome Tracev((stderr, "inflate: dynamic codes block%s\n", 866*ab9e68a2SToomas Soome state->last ? " (last)" : "")); 867*ab9e68a2SToomas Soome state->mode = TABLE; 868*ab9e68a2SToomas Soome break; 869*ab9e68a2SToomas Soome case 3: 870*ab9e68a2SToomas Soome strm->msg = (char *)"invalid block type"; 871*ab9e68a2SToomas Soome state->mode = BAD; 872*ab9e68a2SToomas Soome } 873*ab9e68a2SToomas Soome DROPBITS(2); 874*ab9e68a2SToomas Soome break; 875*ab9e68a2SToomas Soome case STORED: 876*ab9e68a2SToomas Soome BYTEBITS(); /* go to byte boundary */ 877*ab9e68a2SToomas Soome NEEDBITS(32); 878*ab9e68a2SToomas Soome if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { 879*ab9e68a2SToomas Soome strm->msg = (char *)"invalid stored block lengths"; 880*ab9e68a2SToomas Soome state->mode = BAD; 881*ab9e68a2SToomas Soome break; 882*ab9e68a2SToomas Soome } 883*ab9e68a2SToomas Soome state->length = (unsigned)hold & 0xffff; 884*ab9e68a2SToomas Soome Tracev((stderr, "inflate: stored length %u\n", 885*ab9e68a2SToomas Soome state->length)); 886*ab9e68a2SToomas Soome INITBITS(); 887*ab9e68a2SToomas Soome state->mode = COPY_; 888*ab9e68a2SToomas Soome if (flush == Z_TREES) goto inf_leave; 889*ab9e68a2SToomas Soome /* FALLTHROUGH */ 890*ab9e68a2SToomas Soome case COPY_: 891*ab9e68a2SToomas Soome state->mode = COPY; 892*ab9e68a2SToomas Soome /* FALLTHROUGH */ 893*ab9e68a2SToomas Soome case COPY: 894*ab9e68a2SToomas Soome copy = state->length; 895*ab9e68a2SToomas Soome if (copy) { 896*ab9e68a2SToomas Soome if (copy > have) copy = have; 897*ab9e68a2SToomas Soome if (copy > left) copy = left; 898*ab9e68a2SToomas Soome if (copy == 0) goto inf_leave; 899*ab9e68a2SToomas Soome zmemcpy(put, next, copy); 900*ab9e68a2SToomas Soome have -= copy; 901*ab9e68a2SToomas Soome next += copy; 902*ab9e68a2SToomas Soome left -= copy; 903*ab9e68a2SToomas Soome put += copy; 904*ab9e68a2SToomas Soome state->length -= copy; 905*ab9e68a2SToomas Soome break; 906*ab9e68a2SToomas Soome } 907*ab9e68a2SToomas Soome Tracev((stderr, "inflate: stored end\n")); 908*ab9e68a2SToomas Soome state->mode = TYPE; 909*ab9e68a2SToomas Soome break; 910*ab9e68a2SToomas Soome case TABLE: 911*ab9e68a2SToomas Soome NEEDBITS(14); 912*ab9e68a2SToomas Soome state->nlen = BITS(5) + 257; 913*ab9e68a2SToomas Soome DROPBITS(5); 914*ab9e68a2SToomas Soome state->ndist = BITS(5) + 1; 915*ab9e68a2SToomas Soome DROPBITS(5); 916*ab9e68a2SToomas Soome state->ncode = BITS(4) + 4; 917*ab9e68a2SToomas Soome DROPBITS(4); 918*ab9e68a2SToomas Soome #ifndef PKZIP_BUG_WORKAROUND 919*ab9e68a2SToomas Soome if (state->nlen > 286 || state->ndist > 30) { 920*ab9e68a2SToomas Soome strm->msg = (char *)"too many length or distance symbols"; 921*ab9e68a2SToomas Soome state->mode = BAD; 922*ab9e68a2SToomas Soome break; 923*ab9e68a2SToomas Soome } 924*ab9e68a2SToomas Soome #endif 925*ab9e68a2SToomas Soome Tracev((stderr, "inflate: table sizes ok\n")); 926*ab9e68a2SToomas Soome state->have = 0; 927*ab9e68a2SToomas Soome state->mode = LENLENS; 928*ab9e68a2SToomas Soome case LENLENS: 929*ab9e68a2SToomas Soome while (state->have < state->ncode) { 930*ab9e68a2SToomas Soome NEEDBITS(3); 931*ab9e68a2SToomas Soome state->lens[order[state->have++]] = (unsigned short)BITS(3); 932*ab9e68a2SToomas Soome DROPBITS(3); 933*ab9e68a2SToomas Soome } 934*ab9e68a2SToomas Soome while (state->have < 19) 935*ab9e68a2SToomas Soome state->lens[order[state->have++]] = 0; 936*ab9e68a2SToomas Soome state->next = state->codes; 937*ab9e68a2SToomas Soome state->lencode = (const code FAR *)(state->next); 938*ab9e68a2SToomas Soome state->lenbits = 7; 939*ab9e68a2SToomas Soome ret = inflate_table(CODES, state->lens, 19, &(state->next), 940*ab9e68a2SToomas Soome &(state->lenbits), state->work); 941*ab9e68a2SToomas Soome if (ret) { 942*ab9e68a2SToomas Soome strm->msg = (char *)"invalid code lengths set"; 943*ab9e68a2SToomas Soome state->mode = BAD; 944*ab9e68a2SToomas Soome break; 945*ab9e68a2SToomas Soome } 946*ab9e68a2SToomas Soome Tracev((stderr, "inflate: code lengths ok\n")); 947*ab9e68a2SToomas Soome state->have = 0; 948*ab9e68a2SToomas Soome state->mode = CODELENS; 949*ab9e68a2SToomas Soome case CODELENS: 950*ab9e68a2SToomas Soome while (state->have < state->nlen + state->ndist) { 951*ab9e68a2SToomas Soome for (;;) { 952*ab9e68a2SToomas Soome here = state->lencode[BITS(state->lenbits)]; 953*ab9e68a2SToomas Soome if ((unsigned)(here.bits) <= bits) break; 954*ab9e68a2SToomas Soome PULLBYTE(); 955*ab9e68a2SToomas Soome } 956*ab9e68a2SToomas Soome if (here.val < 16) { 957*ab9e68a2SToomas Soome DROPBITS(here.bits); 958*ab9e68a2SToomas Soome state->lens[state->have++] = here.val; 959*ab9e68a2SToomas Soome } 960*ab9e68a2SToomas Soome else { 961*ab9e68a2SToomas Soome if (here.val == 16) { 962*ab9e68a2SToomas Soome NEEDBITS(here.bits + 2); 963*ab9e68a2SToomas Soome DROPBITS(here.bits); 964*ab9e68a2SToomas Soome if (state->have == 0) { 965*ab9e68a2SToomas Soome strm->msg = (char *)"invalid bit length repeat"; 966*ab9e68a2SToomas Soome state->mode = BAD; 967*ab9e68a2SToomas Soome break; 968*ab9e68a2SToomas Soome } 969*ab9e68a2SToomas Soome len = state->lens[state->have - 1]; 970*ab9e68a2SToomas Soome copy = 3 + BITS(2); 971*ab9e68a2SToomas Soome DROPBITS(2); 972*ab9e68a2SToomas Soome } 973*ab9e68a2SToomas Soome else if (here.val == 17) { 974*ab9e68a2SToomas Soome NEEDBITS(here.bits + 3); 975*ab9e68a2SToomas Soome DROPBITS(here.bits); 976*ab9e68a2SToomas Soome len = 0; 977*ab9e68a2SToomas Soome copy = 3 + BITS(3); 978*ab9e68a2SToomas Soome DROPBITS(3); 979*ab9e68a2SToomas Soome } 980*ab9e68a2SToomas Soome else { 981*ab9e68a2SToomas Soome NEEDBITS(here.bits + 7); 982*ab9e68a2SToomas Soome DROPBITS(here.bits); 983*ab9e68a2SToomas Soome len = 0; 984*ab9e68a2SToomas Soome copy = 11 + BITS(7); 985*ab9e68a2SToomas Soome DROPBITS(7); 986*ab9e68a2SToomas Soome } 987*ab9e68a2SToomas Soome if (state->have + copy > state->nlen + state->ndist) { 988*ab9e68a2SToomas Soome strm->msg = (char *)"invalid bit length repeat"; 989*ab9e68a2SToomas Soome state->mode = BAD; 990*ab9e68a2SToomas Soome break; 991*ab9e68a2SToomas Soome } 992*ab9e68a2SToomas Soome while (copy--) 993*ab9e68a2SToomas Soome state->lens[state->have++] = (unsigned short)len; 994*ab9e68a2SToomas Soome } 995*ab9e68a2SToomas Soome } 996*ab9e68a2SToomas Soome 997*ab9e68a2SToomas Soome /* handle error breaks in while */ 998*ab9e68a2SToomas Soome if (state->mode == BAD) break; 999*ab9e68a2SToomas Soome 1000*ab9e68a2SToomas Soome /* check for end-of-block code (better have one) */ 1001*ab9e68a2SToomas Soome if (state->lens[256] == 0) { 1002*ab9e68a2SToomas Soome strm->msg = (char *)"invalid code -- missing end-of-block"; 1003*ab9e68a2SToomas Soome state->mode = BAD; 1004*ab9e68a2SToomas Soome break; 1005*ab9e68a2SToomas Soome } 1006*ab9e68a2SToomas Soome 1007*ab9e68a2SToomas Soome /* build code tables -- note: do not change the lenbits or distbits 1008*ab9e68a2SToomas Soome values here (9 and 6) without reading the comments in inftrees.h 1009*ab9e68a2SToomas Soome concerning the ENOUGH constants, which depend on those values */ 1010*ab9e68a2SToomas Soome state->next = state->codes; 1011*ab9e68a2SToomas Soome state->lencode = (const code FAR *)(state->next); 1012*ab9e68a2SToomas Soome state->lenbits = 9; 1013*ab9e68a2SToomas Soome ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), 1014*ab9e68a2SToomas Soome &(state->lenbits), state->work); 1015*ab9e68a2SToomas Soome if (ret) { 1016*ab9e68a2SToomas Soome strm->msg = (char *)"invalid literal/lengths set"; 1017*ab9e68a2SToomas Soome state->mode = BAD; 1018*ab9e68a2SToomas Soome break; 1019*ab9e68a2SToomas Soome } 1020*ab9e68a2SToomas Soome state->distcode = (const code FAR *)(state->next); 1021*ab9e68a2SToomas Soome state->distbits = 6; 1022*ab9e68a2SToomas Soome ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, 1023*ab9e68a2SToomas Soome &(state->next), &(state->distbits), state->work); 1024*ab9e68a2SToomas Soome if (ret) { 1025*ab9e68a2SToomas Soome strm->msg = (char *)"invalid distances set"; 1026*ab9e68a2SToomas Soome state->mode = BAD; 1027*ab9e68a2SToomas Soome break; 1028*ab9e68a2SToomas Soome } 1029*ab9e68a2SToomas Soome Tracev((stderr, "inflate: codes ok\n")); 1030*ab9e68a2SToomas Soome state->mode = LEN_; 1031*ab9e68a2SToomas Soome if (flush == Z_TREES) goto inf_leave; 1032*ab9e68a2SToomas Soome /* FALLTHROUGH */ 1033*ab9e68a2SToomas Soome case LEN_: 1034*ab9e68a2SToomas Soome state->mode = LEN; 1035*ab9e68a2SToomas Soome /* FALLTHROUGH */ 1036*ab9e68a2SToomas Soome case LEN: 1037*ab9e68a2SToomas Soome if (have >= 6 && left >= 258) { 1038*ab9e68a2SToomas Soome RESTORE(); 1039*ab9e68a2SToomas Soome inflate_fast(strm, out); 1040*ab9e68a2SToomas Soome LOAD(); 1041*ab9e68a2SToomas Soome if (state->mode == TYPE) 1042*ab9e68a2SToomas Soome state->back = -1; 1043*ab9e68a2SToomas Soome break; 1044*ab9e68a2SToomas Soome } 1045*ab9e68a2SToomas Soome state->back = 0; 1046*ab9e68a2SToomas Soome for (;;) { 1047*ab9e68a2SToomas Soome here = state->lencode[BITS(state->lenbits)]; 1048*ab9e68a2SToomas Soome if ((unsigned)(here.bits) <= bits) break; 1049*ab9e68a2SToomas Soome PULLBYTE(); 1050*ab9e68a2SToomas Soome } 1051*ab9e68a2SToomas Soome if (here.op && (here.op & 0xf0) == 0) { 1052*ab9e68a2SToomas Soome last = here; 1053*ab9e68a2SToomas Soome for (;;) { 1054*ab9e68a2SToomas Soome here = state->lencode[last.val + 1055*ab9e68a2SToomas Soome (BITS(last.bits + last.op) >> last.bits)]; 1056*ab9e68a2SToomas Soome if ((unsigned)(last.bits + here.bits) <= bits) break; 1057*ab9e68a2SToomas Soome PULLBYTE(); 1058*ab9e68a2SToomas Soome } 1059*ab9e68a2SToomas Soome DROPBITS(last.bits); 1060*ab9e68a2SToomas Soome state->back += last.bits; 1061*ab9e68a2SToomas Soome } 1062*ab9e68a2SToomas Soome DROPBITS(here.bits); 1063*ab9e68a2SToomas Soome state->back += here.bits; 1064*ab9e68a2SToomas Soome state->length = (unsigned)here.val; 1065*ab9e68a2SToomas Soome if ((int)(here.op) == 0) { 1066*ab9e68a2SToomas Soome Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 1067*ab9e68a2SToomas Soome "inflate: literal '%c'\n" : 1068*ab9e68a2SToomas Soome "inflate: literal 0x%02x\n", here.val)); 1069*ab9e68a2SToomas Soome state->mode = LIT; 1070*ab9e68a2SToomas Soome break; 1071*ab9e68a2SToomas Soome } 1072*ab9e68a2SToomas Soome if (here.op & 32) { 1073*ab9e68a2SToomas Soome Tracevv((stderr, "inflate: end of block\n")); 1074*ab9e68a2SToomas Soome state->back = -1; 1075*ab9e68a2SToomas Soome state->mode = TYPE; 1076*ab9e68a2SToomas Soome break; 1077*ab9e68a2SToomas Soome } 1078*ab9e68a2SToomas Soome if (here.op & 64) { 1079*ab9e68a2SToomas Soome strm->msg = (char *)"invalid literal/length code"; 1080*ab9e68a2SToomas Soome state->mode = BAD; 1081*ab9e68a2SToomas Soome break; 1082*ab9e68a2SToomas Soome } 1083*ab9e68a2SToomas Soome state->extra = (unsigned)(here.op) & 15; 1084*ab9e68a2SToomas Soome state->mode = LENEXT; 1085*ab9e68a2SToomas Soome /* FALLTHROUGH */ 1086*ab9e68a2SToomas Soome case LENEXT: 1087*ab9e68a2SToomas Soome if (state->extra) { 1088*ab9e68a2SToomas Soome NEEDBITS(state->extra); 1089*ab9e68a2SToomas Soome state->length += BITS(state->extra); 1090*ab9e68a2SToomas Soome DROPBITS(state->extra); 1091*ab9e68a2SToomas Soome state->back += state->extra; 1092*ab9e68a2SToomas Soome } 1093*ab9e68a2SToomas Soome Tracevv((stderr, "inflate: length %u\n", state->length)); 1094*ab9e68a2SToomas Soome state->was = state->length; 1095*ab9e68a2SToomas Soome state->mode = DIST; 1096*ab9e68a2SToomas Soome /* FALLTHROUGH */ 1097*ab9e68a2SToomas Soome case DIST: 1098*ab9e68a2SToomas Soome for (;;) { 1099*ab9e68a2SToomas Soome here = state->distcode[BITS(state->distbits)]; 1100*ab9e68a2SToomas Soome if ((unsigned)(here.bits) <= bits) break; 1101*ab9e68a2SToomas Soome PULLBYTE(); 1102*ab9e68a2SToomas Soome } 1103*ab9e68a2SToomas Soome if ((here.op & 0xf0) == 0) { 1104*ab9e68a2SToomas Soome last = here; 1105*ab9e68a2SToomas Soome for (;;) { 1106*ab9e68a2SToomas Soome here = state->distcode[last.val + 1107*ab9e68a2SToomas Soome (BITS(last.bits + last.op) >> last.bits)]; 1108*ab9e68a2SToomas Soome if ((unsigned)(last.bits + here.bits) <= bits) break; 1109*ab9e68a2SToomas Soome PULLBYTE(); 1110*ab9e68a2SToomas Soome } 1111*ab9e68a2SToomas Soome DROPBITS(last.bits); 1112*ab9e68a2SToomas Soome state->back += last.bits; 1113*ab9e68a2SToomas Soome } 1114*ab9e68a2SToomas Soome DROPBITS(here.bits); 1115*ab9e68a2SToomas Soome state->back += here.bits; 1116*ab9e68a2SToomas Soome if (here.op & 64) { 1117*ab9e68a2SToomas Soome strm->msg = (char *)"invalid distance code"; 1118*ab9e68a2SToomas Soome state->mode = BAD; 1119*ab9e68a2SToomas Soome break; 1120*ab9e68a2SToomas Soome } 1121*ab9e68a2SToomas Soome state->offset = (unsigned)here.val; 1122*ab9e68a2SToomas Soome state->extra = (unsigned)(here.op) & 15; 1123*ab9e68a2SToomas Soome state->mode = DISTEXT; 1124*ab9e68a2SToomas Soome /* FALLTHROUGH */ 1125*ab9e68a2SToomas Soome case DISTEXT: 1126*ab9e68a2SToomas Soome if (state->extra) { 1127*ab9e68a2SToomas Soome NEEDBITS(state->extra); 1128*ab9e68a2SToomas Soome state->offset += BITS(state->extra); 1129*ab9e68a2SToomas Soome DROPBITS(state->extra); 1130*ab9e68a2SToomas Soome state->back += state->extra; 1131*ab9e68a2SToomas Soome } 1132*ab9e68a2SToomas Soome #ifdef INFLATE_STRICT 1133*ab9e68a2SToomas Soome if (state->offset > state->dmax) { 1134*ab9e68a2SToomas Soome strm->msg = (char *)"invalid distance too far back"; 1135*ab9e68a2SToomas Soome state->mode = BAD; 1136*ab9e68a2SToomas Soome break; 1137*ab9e68a2SToomas Soome } 1138*ab9e68a2SToomas Soome #endif 1139*ab9e68a2SToomas Soome Tracevv((stderr, "inflate: distance %u\n", state->offset)); 1140*ab9e68a2SToomas Soome state->mode = MATCH; 1141*ab9e68a2SToomas Soome /* FALLTHROUGH */ 1142*ab9e68a2SToomas Soome case MATCH: 1143*ab9e68a2SToomas Soome if (left == 0) goto inf_leave; 1144*ab9e68a2SToomas Soome copy = out - left; 1145*ab9e68a2SToomas Soome if (state->offset > copy) { /* copy from window */ 1146*ab9e68a2SToomas Soome copy = state->offset - copy; 1147*ab9e68a2SToomas Soome if (copy > state->whave) { 1148*ab9e68a2SToomas Soome if (state->sane) { 1149*ab9e68a2SToomas Soome strm->msg = (char *)"invalid distance too far back"; 1150*ab9e68a2SToomas Soome state->mode = BAD; 1151*ab9e68a2SToomas Soome break; 1152*ab9e68a2SToomas Soome } 1153*ab9e68a2SToomas Soome #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 1154*ab9e68a2SToomas Soome Trace((stderr, "inflate.c too far\n")); 1155*ab9e68a2SToomas Soome copy -= state->whave; 1156*ab9e68a2SToomas Soome if (copy > state->length) copy = state->length; 1157*ab9e68a2SToomas Soome if (copy > left) copy = left; 1158*ab9e68a2SToomas Soome left -= copy; 1159*ab9e68a2SToomas Soome state->length -= copy; 1160*ab9e68a2SToomas Soome do { 1161*ab9e68a2SToomas Soome *put++ = 0; 1162*ab9e68a2SToomas Soome } while (--copy); 1163*ab9e68a2SToomas Soome if (state->length == 0) state->mode = LEN; 1164*ab9e68a2SToomas Soome break; 1165*ab9e68a2SToomas Soome #endif 1166*ab9e68a2SToomas Soome } 1167*ab9e68a2SToomas Soome if (copy > state->wnext) { 1168*ab9e68a2SToomas Soome copy -= state->wnext; 1169*ab9e68a2SToomas Soome from = state->window + (state->wsize - copy); 1170*ab9e68a2SToomas Soome } 1171*ab9e68a2SToomas Soome else 1172*ab9e68a2SToomas Soome from = state->window + (state->wnext - copy); 1173*ab9e68a2SToomas Soome if (copy > state->length) copy = state->length; 1174*ab9e68a2SToomas Soome } 1175*ab9e68a2SToomas Soome else { /* copy from output */ 1176*ab9e68a2SToomas Soome from = put - state->offset; 1177*ab9e68a2SToomas Soome copy = state->length; 1178*ab9e68a2SToomas Soome } 1179*ab9e68a2SToomas Soome if (copy > left) copy = left; 1180*ab9e68a2SToomas Soome left -= copy; 1181*ab9e68a2SToomas Soome state->length -= copy; 1182*ab9e68a2SToomas Soome do { 1183*ab9e68a2SToomas Soome *put++ = *from++; 1184*ab9e68a2SToomas Soome } while (--copy); 1185*ab9e68a2SToomas Soome if (state->length == 0) state->mode = LEN; 1186*ab9e68a2SToomas Soome break; 1187*ab9e68a2SToomas Soome case LIT: 1188*ab9e68a2SToomas Soome if (left == 0) goto inf_leave; 1189*ab9e68a2SToomas Soome *put++ = (unsigned char)(state->length); 1190*ab9e68a2SToomas Soome left--; 1191*ab9e68a2SToomas Soome state->mode = LEN; 1192*ab9e68a2SToomas Soome break; 1193*ab9e68a2SToomas Soome case CHECK: 1194*ab9e68a2SToomas Soome if (state->wrap) { 1195*ab9e68a2SToomas Soome NEEDBITS(32); 1196*ab9e68a2SToomas Soome out -= left; 1197*ab9e68a2SToomas Soome strm->total_out += out; 1198*ab9e68a2SToomas Soome state->total += out; 1199*ab9e68a2SToomas Soome if ((state->wrap & 4) && out) 1200*ab9e68a2SToomas Soome strm->adler = state->check = 1201*ab9e68a2SToomas Soome UPDATE(state->check, put - out, out); 1202*ab9e68a2SToomas Soome out = left; 1203*ab9e68a2SToomas Soome if ((state->wrap & 4) && ( 1204*ab9e68a2SToomas Soome #ifdef GUNZIP 1205*ab9e68a2SToomas Soome state->flags ? hold : 1206*ab9e68a2SToomas Soome #endif 1207*ab9e68a2SToomas Soome ZSWAP32(hold)) != state->check) { 1208*ab9e68a2SToomas Soome strm->msg = (char *)"incorrect data check"; 1209*ab9e68a2SToomas Soome state->mode = BAD; 1210*ab9e68a2SToomas Soome break; 1211*ab9e68a2SToomas Soome } 1212*ab9e68a2SToomas Soome INITBITS(); 1213*ab9e68a2SToomas Soome Tracev((stderr, "inflate: check matches trailer\n")); 1214*ab9e68a2SToomas Soome } 1215*ab9e68a2SToomas Soome #ifdef GUNZIP 1216*ab9e68a2SToomas Soome state->mode = LENGTH; 1217*ab9e68a2SToomas Soome /* FALLTHROUGH */ 1218*ab9e68a2SToomas Soome case LENGTH: 1219*ab9e68a2SToomas Soome if (state->wrap && state->flags) { 1220*ab9e68a2SToomas Soome NEEDBITS(32); 1221*ab9e68a2SToomas Soome if (hold != (state->total & 0xffffffffUL)) { 1222*ab9e68a2SToomas Soome strm->msg = (char *)"incorrect length check"; 1223*ab9e68a2SToomas Soome state->mode = BAD; 1224*ab9e68a2SToomas Soome break; 1225*ab9e68a2SToomas Soome } 1226*ab9e68a2SToomas Soome INITBITS(); 1227*ab9e68a2SToomas Soome Tracev((stderr, "inflate: length matches trailer\n")); 1228*ab9e68a2SToomas Soome } 1229*ab9e68a2SToomas Soome #endif 1230*ab9e68a2SToomas Soome state->mode = DONE; 1231*ab9e68a2SToomas Soome /* FALLTHROUGH */ 1232*ab9e68a2SToomas Soome case DONE: 1233*ab9e68a2SToomas Soome ret = Z_STREAM_END; 1234*ab9e68a2SToomas Soome goto inf_leave; 1235*ab9e68a2SToomas Soome case BAD: 1236*ab9e68a2SToomas Soome ret = Z_DATA_ERROR; 1237*ab9e68a2SToomas Soome goto inf_leave; 1238*ab9e68a2SToomas Soome case MEM: 1239*ab9e68a2SToomas Soome return Z_MEM_ERROR; 1240*ab9e68a2SToomas Soome case SYNC: 1241*ab9e68a2SToomas Soome default: 1242*ab9e68a2SToomas Soome return Z_STREAM_ERROR; 1243*ab9e68a2SToomas Soome } 1244*ab9e68a2SToomas Soome 1245*ab9e68a2SToomas Soome /* 1246*ab9e68a2SToomas Soome Return from inflate(), updating the total counts and the check value. 1247*ab9e68a2SToomas Soome If there was no progress during the inflate() call, return a buffer 1248*ab9e68a2SToomas Soome error. Call updatewindow() to create and/or update the window state. 1249*ab9e68a2SToomas Soome Note: a memory error from inflate() is non-recoverable. 1250*ab9e68a2SToomas Soome */ 1251*ab9e68a2SToomas Soome inf_leave: 1252*ab9e68a2SToomas Soome RESTORE(); 1253*ab9e68a2SToomas Soome if (state->wsize || (out != strm->avail_out && state->mode < BAD && 1254*ab9e68a2SToomas Soome (state->mode < CHECK || flush != Z_FINISH))) 1255*ab9e68a2SToomas Soome if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { 1256*ab9e68a2SToomas Soome state->mode = MEM; 1257*ab9e68a2SToomas Soome return Z_MEM_ERROR; 1258*ab9e68a2SToomas Soome } 1259*ab9e68a2SToomas Soome in -= strm->avail_in; 1260*ab9e68a2SToomas Soome out -= strm->avail_out; 1261*ab9e68a2SToomas Soome strm->total_in += in; 1262*ab9e68a2SToomas Soome strm->total_out += out; 1263*ab9e68a2SToomas Soome state->total += out; 1264*ab9e68a2SToomas Soome if ((state->wrap & 4) && out) 1265*ab9e68a2SToomas Soome strm->adler = state->check = 1266*ab9e68a2SToomas Soome UPDATE(state->check, strm->next_out - out, out); 1267*ab9e68a2SToomas Soome strm->data_type = (int)state->bits + (state->last ? 64 : 0) + 1268*ab9e68a2SToomas Soome (state->mode == TYPE ? 128 : 0) + 1269*ab9e68a2SToomas Soome (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); 1270*ab9e68a2SToomas Soome if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) 1271*ab9e68a2SToomas Soome ret = Z_BUF_ERROR; 1272*ab9e68a2SToomas Soome return ret; 1273*ab9e68a2SToomas Soome } 1274*ab9e68a2SToomas Soome 1275*ab9e68a2SToomas Soome int ZEXPORT inflateEnd(z_streamp strm) 1276*ab9e68a2SToomas Soome { 1277*ab9e68a2SToomas Soome struct inflate_state FAR *state; 1278*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) 1279*ab9e68a2SToomas Soome return Z_STREAM_ERROR; 1280*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 1281*ab9e68a2SToomas Soome if (state->window != Z_NULL) ZFREE(strm, state->window); 1282*ab9e68a2SToomas Soome ZFREE(strm, strm->state); 1283*ab9e68a2SToomas Soome strm->state = Z_NULL; 1284*ab9e68a2SToomas Soome Tracev((stderr, "inflate: end\n")); 1285*ab9e68a2SToomas Soome return Z_OK; 1286*ab9e68a2SToomas Soome } 1287*ab9e68a2SToomas Soome 1288*ab9e68a2SToomas Soome int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, 1289*ab9e68a2SToomas Soome uInt *dictLength) 1290*ab9e68a2SToomas Soome { 1291*ab9e68a2SToomas Soome struct inflate_state FAR *state; 1292*ab9e68a2SToomas Soome 1293*ab9e68a2SToomas Soome /* check state */ 1294*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1295*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 1296*ab9e68a2SToomas Soome 1297*ab9e68a2SToomas Soome /* copy dictionary */ 1298*ab9e68a2SToomas Soome if (state->whave && dictionary != Z_NULL) { 1299*ab9e68a2SToomas Soome zmemcpy(dictionary, state->window + state->wnext, 1300*ab9e68a2SToomas Soome state->whave - state->wnext); 1301*ab9e68a2SToomas Soome zmemcpy(dictionary + state->whave - state->wnext, 1302*ab9e68a2SToomas Soome state->window, state->wnext); 1303*ab9e68a2SToomas Soome } 1304*ab9e68a2SToomas Soome if (dictLength != Z_NULL) 1305*ab9e68a2SToomas Soome *dictLength = state->whave; 1306*ab9e68a2SToomas Soome return Z_OK; 1307*ab9e68a2SToomas Soome } 1308*ab9e68a2SToomas Soome 1309*ab9e68a2SToomas Soome int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, 1310*ab9e68a2SToomas Soome uInt dictLength) 1311*ab9e68a2SToomas Soome { 1312*ab9e68a2SToomas Soome struct inflate_state FAR *state; 1313*ab9e68a2SToomas Soome unsigned long dictid; 1314*ab9e68a2SToomas Soome int ret; 1315*ab9e68a2SToomas Soome 1316*ab9e68a2SToomas Soome /* check state */ 1317*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1318*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 1319*ab9e68a2SToomas Soome if (state->wrap != 0 && state->mode != DICT) 1320*ab9e68a2SToomas Soome return Z_STREAM_ERROR; 1321*ab9e68a2SToomas Soome 1322*ab9e68a2SToomas Soome /* check for correct dictionary identifier */ 1323*ab9e68a2SToomas Soome if (state->mode == DICT) { 1324*ab9e68a2SToomas Soome dictid = adler32(0L, Z_NULL, 0); 1325*ab9e68a2SToomas Soome dictid = adler32(dictid, dictionary, dictLength); 1326*ab9e68a2SToomas Soome if (dictid != state->check) 1327*ab9e68a2SToomas Soome return Z_DATA_ERROR; 1328*ab9e68a2SToomas Soome } 1329*ab9e68a2SToomas Soome 1330*ab9e68a2SToomas Soome /* copy dictionary to window using updatewindow(), which will amend the 1331*ab9e68a2SToomas Soome existing dictionary if appropriate */ 1332*ab9e68a2SToomas Soome ret = updatewindow(strm, dictionary + dictLength, dictLength); 1333*ab9e68a2SToomas Soome if (ret) { 1334*ab9e68a2SToomas Soome state->mode = MEM; 1335*ab9e68a2SToomas Soome return Z_MEM_ERROR; 1336*ab9e68a2SToomas Soome } 1337*ab9e68a2SToomas Soome state->havedict = 1; 1338*ab9e68a2SToomas Soome Tracev((stderr, "inflate: dictionary set\n")); 1339*ab9e68a2SToomas Soome return Z_OK; 1340*ab9e68a2SToomas Soome } 1341*ab9e68a2SToomas Soome 1342*ab9e68a2SToomas Soome int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) 1343*ab9e68a2SToomas Soome { 1344*ab9e68a2SToomas Soome struct inflate_state FAR *state; 1345*ab9e68a2SToomas Soome 1346*ab9e68a2SToomas Soome /* check state */ 1347*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1348*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 1349*ab9e68a2SToomas Soome if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; 1350*ab9e68a2SToomas Soome 1351*ab9e68a2SToomas Soome /* save header structure */ 1352*ab9e68a2SToomas Soome state->head = head; 1353*ab9e68a2SToomas Soome head->done = 0; 1354*ab9e68a2SToomas Soome return Z_OK; 1355*ab9e68a2SToomas Soome } 1356*ab9e68a2SToomas Soome 1357*ab9e68a2SToomas Soome /* 1358*ab9e68a2SToomas Soome Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found 1359*ab9e68a2SToomas Soome or when out of input. When called, *have is the number of pattern bytes 1360*ab9e68a2SToomas Soome found in order so far, in 0..3. On return *have is updated to the new 1361*ab9e68a2SToomas Soome state. If on return *have equals four, then the pattern was found and the 1362*ab9e68a2SToomas Soome return value is how many bytes were read including the last byte of the 1363*ab9e68a2SToomas Soome pattern. If *have is less than four, then the pattern has not been found 1364*ab9e68a2SToomas Soome yet and the return value is len. In the latter case, syncsearch() can be 1365*ab9e68a2SToomas Soome called again with more data and the *have state. *have is initialized to 1366*ab9e68a2SToomas Soome zero for the first call. 1367*ab9e68a2SToomas Soome */ 1368*ab9e68a2SToomas Soome local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, 1369*ab9e68a2SToomas Soome unsigned len) 1370*ab9e68a2SToomas Soome { 1371*ab9e68a2SToomas Soome unsigned got; 1372*ab9e68a2SToomas Soome unsigned next; 1373*ab9e68a2SToomas Soome 1374*ab9e68a2SToomas Soome got = *have; 1375*ab9e68a2SToomas Soome next = 0; 1376*ab9e68a2SToomas Soome while (next < len && got < 4) { 1377*ab9e68a2SToomas Soome if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) 1378*ab9e68a2SToomas Soome got++; 1379*ab9e68a2SToomas Soome else if (buf[next]) 1380*ab9e68a2SToomas Soome got = 0; 1381*ab9e68a2SToomas Soome else 1382*ab9e68a2SToomas Soome got = 4 - got; 1383*ab9e68a2SToomas Soome next++; 1384*ab9e68a2SToomas Soome } 1385*ab9e68a2SToomas Soome *have = got; 1386*ab9e68a2SToomas Soome return next; 1387*ab9e68a2SToomas Soome } 1388*ab9e68a2SToomas Soome 1389*ab9e68a2SToomas Soome int ZEXPORT inflateSync(z_streamp strm) 1390*ab9e68a2SToomas Soome { 1391*ab9e68a2SToomas Soome unsigned len; /* number of bytes to look at or looked at */ 1392*ab9e68a2SToomas Soome unsigned long in, out; /* temporary to save total_in and total_out */ 1393*ab9e68a2SToomas Soome unsigned char buf[4]; /* to restore bit buffer to byte string */ 1394*ab9e68a2SToomas Soome struct inflate_state FAR *state; 1395*ab9e68a2SToomas Soome 1396*ab9e68a2SToomas Soome /* check parameters */ 1397*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1398*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 1399*ab9e68a2SToomas Soome if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; 1400*ab9e68a2SToomas Soome 1401*ab9e68a2SToomas Soome /* if first time, start search in bit buffer */ 1402*ab9e68a2SToomas Soome if (state->mode != SYNC) { 1403*ab9e68a2SToomas Soome state->mode = SYNC; 1404*ab9e68a2SToomas Soome state->hold <<= state->bits & 7; 1405*ab9e68a2SToomas Soome state->bits -= state->bits & 7; 1406*ab9e68a2SToomas Soome len = 0; 1407*ab9e68a2SToomas Soome while (state->bits >= 8) { 1408*ab9e68a2SToomas Soome buf[len++] = (unsigned char)(state->hold); 1409*ab9e68a2SToomas Soome state->hold >>= 8; 1410*ab9e68a2SToomas Soome state->bits -= 8; 1411*ab9e68a2SToomas Soome } 1412*ab9e68a2SToomas Soome state->have = 0; 1413*ab9e68a2SToomas Soome syncsearch(&(state->have), buf, len); 1414*ab9e68a2SToomas Soome } 1415*ab9e68a2SToomas Soome 1416*ab9e68a2SToomas Soome /* search available input */ 1417*ab9e68a2SToomas Soome len = syncsearch(&(state->have), strm->next_in, strm->avail_in); 1418*ab9e68a2SToomas Soome strm->avail_in -= len; 1419*ab9e68a2SToomas Soome strm->next_in += len; 1420*ab9e68a2SToomas Soome strm->total_in += len; 1421*ab9e68a2SToomas Soome 1422*ab9e68a2SToomas Soome /* return no joy or set up to restart inflate() on a new block */ 1423*ab9e68a2SToomas Soome if (state->have != 4) return Z_DATA_ERROR; 1424*ab9e68a2SToomas Soome in = strm->total_in; out = strm->total_out; 1425*ab9e68a2SToomas Soome inflateReset(strm); 1426*ab9e68a2SToomas Soome strm->total_in = in; strm->total_out = out; 1427*ab9e68a2SToomas Soome state->mode = TYPE; 1428*ab9e68a2SToomas Soome return Z_OK; 1429*ab9e68a2SToomas Soome } 1430*ab9e68a2SToomas Soome 1431*ab9e68a2SToomas Soome /* 1432*ab9e68a2SToomas Soome Returns true if inflate is currently at the end of a block generated by 1433*ab9e68a2SToomas Soome Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP 1434*ab9e68a2SToomas Soome implementation to provide an additional safety check. PPP uses 1435*ab9e68a2SToomas Soome Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored 1436*ab9e68a2SToomas Soome block. When decompressing, PPP checks that at the end of input packet, 1437*ab9e68a2SToomas Soome inflate is waiting for these length bytes. 1438*ab9e68a2SToomas Soome */ 1439*ab9e68a2SToomas Soome int ZEXPORT inflateSyncPoint(z_streamp strm) 1440*ab9e68a2SToomas Soome { 1441*ab9e68a2SToomas Soome struct inflate_state FAR *state; 1442*ab9e68a2SToomas Soome 1443*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1444*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 1445*ab9e68a2SToomas Soome return state->mode == STORED && state->bits == 0; 1446*ab9e68a2SToomas Soome } 1447*ab9e68a2SToomas Soome 1448*ab9e68a2SToomas Soome int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) 1449*ab9e68a2SToomas Soome { 1450*ab9e68a2SToomas Soome struct inflate_state FAR *state; 1451*ab9e68a2SToomas Soome struct inflate_state FAR *copy; 1452*ab9e68a2SToomas Soome unsigned char FAR *window; 1453*ab9e68a2SToomas Soome unsigned wsize; 1454*ab9e68a2SToomas Soome 1455*ab9e68a2SToomas Soome /* check input */ 1456*ab9e68a2SToomas Soome if (inflateStateCheck(source) || dest == Z_NULL) 1457*ab9e68a2SToomas Soome return Z_STREAM_ERROR; 1458*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)source->state; 1459*ab9e68a2SToomas Soome 1460*ab9e68a2SToomas Soome /* allocate space */ 1461*ab9e68a2SToomas Soome copy = (struct inflate_state FAR *) 1462*ab9e68a2SToomas Soome ZALLOC(source, 1, sizeof(struct inflate_state)); 1463*ab9e68a2SToomas Soome if (copy == Z_NULL) return Z_MEM_ERROR; 1464*ab9e68a2SToomas Soome window = Z_NULL; 1465*ab9e68a2SToomas Soome if (state->window != Z_NULL) { 1466*ab9e68a2SToomas Soome window = (unsigned char FAR *) 1467*ab9e68a2SToomas Soome ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); 1468*ab9e68a2SToomas Soome if (window == Z_NULL) { 1469*ab9e68a2SToomas Soome ZFREE(source, copy); 1470*ab9e68a2SToomas Soome return Z_MEM_ERROR; 1471*ab9e68a2SToomas Soome } 1472*ab9e68a2SToomas Soome } 1473*ab9e68a2SToomas Soome 1474*ab9e68a2SToomas Soome /* copy state */ 1475*ab9e68a2SToomas Soome zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); 1476*ab9e68a2SToomas Soome zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); 1477*ab9e68a2SToomas Soome copy->strm = dest; 1478*ab9e68a2SToomas Soome if (state->lencode >= state->codes && 1479*ab9e68a2SToomas Soome state->lencode <= state->codes + ENOUGH - 1) { 1480*ab9e68a2SToomas Soome copy->lencode = copy->codes + (state->lencode - state->codes); 1481*ab9e68a2SToomas Soome copy->distcode = copy->codes + (state->distcode - state->codes); 1482*ab9e68a2SToomas Soome } 1483*ab9e68a2SToomas Soome copy->next = copy->codes + (state->next - state->codes); 1484*ab9e68a2SToomas Soome if (window != Z_NULL) { 1485*ab9e68a2SToomas Soome wsize = 1U << state->wbits; 1486*ab9e68a2SToomas Soome zmemcpy(window, state->window, wsize); 1487*ab9e68a2SToomas Soome } 1488*ab9e68a2SToomas Soome copy->window = window; 1489*ab9e68a2SToomas Soome dest->state = (struct internal_state FAR *)copy; 1490*ab9e68a2SToomas Soome return Z_OK; 1491*ab9e68a2SToomas Soome } 1492*ab9e68a2SToomas Soome 1493*ab9e68a2SToomas Soome int ZEXPORT inflateUndermine(z_streamp strm, int subvert) 1494*ab9e68a2SToomas Soome { 1495*ab9e68a2SToomas Soome struct inflate_state FAR *state; 1496*ab9e68a2SToomas Soome 1497*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1498*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 1499*ab9e68a2SToomas Soome #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 1500*ab9e68a2SToomas Soome state->sane = !subvert; 1501*ab9e68a2SToomas Soome return Z_OK; 1502*ab9e68a2SToomas Soome #else 1503*ab9e68a2SToomas Soome (void)subvert; 1504*ab9e68a2SToomas Soome state->sane = 1; 1505*ab9e68a2SToomas Soome return Z_DATA_ERROR; 1506*ab9e68a2SToomas Soome #endif 1507*ab9e68a2SToomas Soome } 1508*ab9e68a2SToomas Soome 1509*ab9e68a2SToomas Soome int ZEXPORT inflateValidate(z_streamp strm, int check) 1510*ab9e68a2SToomas Soome { 1511*ab9e68a2SToomas Soome struct inflate_state FAR *state; 1512*ab9e68a2SToomas Soome 1513*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1514*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 1515*ab9e68a2SToomas Soome if (check) 1516*ab9e68a2SToomas Soome state->wrap |= 4; 1517*ab9e68a2SToomas Soome else 1518*ab9e68a2SToomas Soome state->wrap &= ~4; 1519*ab9e68a2SToomas Soome return Z_OK; 1520*ab9e68a2SToomas Soome } 1521*ab9e68a2SToomas Soome 1522*ab9e68a2SToomas Soome long ZEXPORT inflateMark(z_streamp strm) 1523*ab9e68a2SToomas Soome { 1524*ab9e68a2SToomas Soome struct inflate_state FAR *state; 1525*ab9e68a2SToomas Soome 1526*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) 1527*ab9e68a2SToomas Soome return -(1L << 16); 1528*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 1529*ab9e68a2SToomas Soome return (long)(((unsigned long)((long)state->back)) << 16) + 1530*ab9e68a2SToomas Soome (state->mode == COPY ? state->length : 1531*ab9e68a2SToomas Soome (state->mode == MATCH ? state->was - state->length : 0)); 1532*ab9e68a2SToomas Soome } 1533*ab9e68a2SToomas Soome 1534*ab9e68a2SToomas Soome unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) 1535*ab9e68a2SToomas Soome { 1536*ab9e68a2SToomas Soome struct inflate_state FAR *state; 1537*ab9e68a2SToomas Soome if (inflateStateCheck(strm)) return (unsigned long)-1; 1538*ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 1539*ab9e68a2SToomas Soome return (unsigned long)(state->next - state->codes); 1540*ab9e68a2SToomas Soome } 1541