1221b1638SMasahiro Yamada /* inflate.c -- zlib decompression 2a194255dSDaniel Boulby * Copyright (C) 1995-2022 Mark Adler 3221b1638SMasahiro Yamada * For conditions of distribution and use, see copyright notice in zlib.h 4221b1638SMasahiro Yamada */ 5221b1638SMasahiro Yamada 6221b1638SMasahiro Yamada /* 7221b1638SMasahiro Yamada * Change history: 8221b1638SMasahiro Yamada * 9221b1638SMasahiro Yamada * 1.2.beta0 24 Nov 2002 10221b1638SMasahiro Yamada * - First version -- complete rewrite of inflate to simplify code, avoid 11221b1638SMasahiro Yamada * creation of window when not needed, minimize use of window when it is 12221b1638SMasahiro Yamada * needed, make inffast.c even faster, implement gzip decoding, and to 13221b1638SMasahiro Yamada * improve code readability and style over the previous zlib inflate code 14221b1638SMasahiro Yamada * 15221b1638SMasahiro Yamada * 1.2.beta1 25 Nov 2002 16221b1638SMasahiro Yamada * - Use pointers for available input and output checking in inffast.c 17221b1638SMasahiro Yamada * - Remove input and output counters in inffast.c 18221b1638SMasahiro Yamada * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 19221b1638SMasahiro Yamada * - Remove unnecessary second byte pull from length extra in inffast.c 20221b1638SMasahiro Yamada * - Unroll direct copy to three copies per loop in inffast.c 21221b1638SMasahiro Yamada * 22221b1638SMasahiro Yamada * 1.2.beta2 4 Dec 2002 23221b1638SMasahiro Yamada * - Change external routine names to reduce potential conflicts 24221b1638SMasahiro Yamada * - Correct filename to inffixed.h for fixed tables in inflate.c 25221b1638SMasahiro Yamada * - Make hbuf[] unsigned char to match parameter type in inflate.c 26221b1638SMasahiro Yamada * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) 27221b1638SMasahiro Yamada * to avoid negation problem on Alphas (64 bit) in inflate.c 28221b1638SMasahiro Yamada * 29221b1638SMasahiro Yamada * 1.2.beta3 22 Dec 2002 30221b1638SMasahiro Yamada * - Add comments on state->bits assertion in inffast.c 31221b1638SMasahiro Yamada * - Add comments on op field in inftrees.h 32221b1638SMasahiro Yamada * - Fix bug in reuse of allocated window after inflateReset() 33221b1638SMasahiro Yamada * - Remove bit fields--back to byte structure for speed 34221b1638SMasahiro Yamada * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths 35221b1638SMasahiro Yamada * - Change post-increments to pre-increments in inflate_fast(), PPC biased? 36221b1638SMasahiro Yamada * - Add compile time option, POSTINC, to use post-increments instead (Intel?) 37221b1638SMasahiro Yamada * - Make MATCH copy in inflate() much faster for when inflate_fast() not used 38221b1638SMasahiro Yamada * - Use local copies of stream next and avail values, as well as local bit 39221b1638SMasahiro Yamada * buffer and bit count in inflate()--for speed when inflate_fast() not used 40221b1638SMasahiro Yamada * 41221b1638SMasahiro Yamada * 1.2.beta4 1 Jan 2003 42221b1638SMasahiro Yamada * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings 43221b1638SMasahiro Yamada * - Move a comment on output buffer sizes from inffast.c to inflate.c 44221b1638SMasahiro Yamada * - Add comments in inffast.c to introduce the inflate_fast() routine 45221b1638SMasahiro Yamada * - Rearrange window copies in inflate_fast() for speed and simplification 46221b1638SMasahiro Yamada * - Unroll last copy for window match in inflate_fast() 47221b1638SMasahiro Yamada * - Use local copies of window variables in inflate_fast() for speed 48221b1638SMasahiro Yamada * - Pull out common wnext == 0 case for speed in inflate_fast() 49221b1638SMasahiro Yamada * - Make op and len in inflate_fast() unsigned for consistency 50221b1638SMasahiro Yamada * - Add FAR to lcode and dcode declarations in inflate_fast() 51221b1638SMasahiro Yamada * - Simplified bad distance check in inflate_fast() 52221b1638SMasahiro Yamada * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new 53221b1638SMasahiro Yamada * source file infback.c to provide a call-back interface to inflate for 54221b1638SMasahiro Yamada * programs like gzip and unzip -- uses window as output buffer to avoid 55221b1638SMasahiro Yamada * window copying 56221b1638SMasahiro Yamada * 57221b1638SMasahiro Yamada * 1.2.beta5 1 Jan 2003 58221b1638SMasahiro Yamada * - Improved inflateBack() interface to allow the caller to provide initial 59221b1638SMasahiro Yamada * input in strm. 60221b1638SMasahiro Yamada * - Fixed stored blocks bug in inflateBack() 61221b1638SMasahiro Yamada * 62221b1638SMasahiro Yamada * 1.2.beta6 4 Jan 2003 63221b1638SMasahiro Yamada * - Added comments in inffast.c on effectiveness of POSTINC 64221b1638SMasahiro Yamada * - Typecasting all around to reduce compiler warnings 65221b1638SMasahiro Yamada * - Changed loops from while (1) or do {} while (1) to for (;;), again to 66221b1638SMasahiro Yamada * make compilers happy 67221b1638SMasahiro Yamada * - Changed type of window in inflateBackInit() to unsigned char * 68221b1638SMasahiro Yamada * 69221b1638SMasahiro Yamada * 1.2.beta7 27 Jan 2003 70221b1638SMasahiro Yamada * - Changed many types to unsigned or unsigned short to avoid warnings 71221b1638SMasahiro Yamada * - Added inflateCopy() function 72221b1638SMasahiro Yamada * 73221b1638SMasahiro Yamada * 1.2.0 9 Mar 2003 74221b1638SMasahiro Yamada * - Changed inflateBack() interface to provide separate opaque descriptors 75221b1638SMasahiro Yamada * for the in() and out() functions 76221b1638SMasahiro Yamada * - Changed inflateBack() argument and in_func typedef to swap the length 77221b1638SMasahiro Yamada * and buffer address return values for the input function 78221b1638SMasahiro Yamada * - Check next_in and next_out for Z_NULL on entry to inflate() 79221b1638SMasahiro Yamada * 80221b1638SMasahiro Yamada * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. 81221b1638SMasahiro Yamada */ 82221b1638SMasahiro Yamada 83221b1638SMasahiro Yamada #include "zutil.h" 84221b1638SMasahiro Yamada #include "inftrees.h" 85221b1638SMasahiro Yamada #include "inflate.h" 86221b1638SMasahiro Yamada #include "inffast.h" 87221b1638SMasahiro Yamada 88221b1638SMasahiro Yamada #ifdef MAKEFIXED 89221b1638SMasahiro Yamada # ifndef BUILDFIXED 90221b1638SMasahiro Yamada # define BUILDFIXED 91221b1638SMasahiro Yamada # endif 92221b1638SMasahiro Yamada #endif 93221b1638SMasahiro Yamada 94*fd39217aSManish Pandey local int inflateStateCheck(z_streamp strm) { 95221b1638SMasahiro Yamada struct inflate_state FAR *state; 96221b1638SMasahiro Yamada if (strm == Z_NULL || 97221b1638SMasahiro Yamada strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) 98221b1638SMasahiro Yamada return 1; 99221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 100221b1638SMasahiro Yamada if (state == Z_NULL || state->strm != strm || 101221b1638SMasahiro Yamada state->mode < HEAD || state->mode > SYNC) 102221b1638SMasahiro Yamada return 1; 103221b1638SMasahiro Yamada return 0; 104221b1638SMasahiro Yamada } 105221b1638SMasahiro Yamada 106*fd39217aSManish Pandey int ZEXPORT inflateResetKeep(z_streamp strm) { 107221b1638SMasahiro Yamada struct inflate_state FAR *state; 108221b1638SMasahiro Yamada 109221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 110221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 111221b1638SMasahiro Yamada strm->total_in = strm->total_out = state->total = 0; 112221b1638SMasahiro Yamada strm->msg = Z_NULL; 113221b1638SMasahiro Yamada if (state->wrap) /* to support ill-conceived Java test suite */ 114221b1638SMasahiro Yamada strm->adler = state->wrap & 1; 115221b1638SMasahiro Yamada state->mode = HEAD; 116221b1638SMasahiro Yamada state->last = 0; 117221b1638SMasahiro Yamada state->havedict = 0; 118a194255dSDaniel Boulby state->flags = -1; 119221b1638SMasahiro Yamada state->dmax = 32768U; 120221b1638SMasahiro Yamada state->head = Z_NULL; 121221b1638SMasahiro Yamada state->hold = 0; 122221b1638SMasahiro Yamada state->bits = 0; 123221b1638SMasahiro Yamada state->lencode = state->distcode = state->next = state->codes; 124221b1638SMasahiro Yamada state->sane = 1; 125221b1638SMasahiro Yamada state->back = -1; 126221b1638SMasahiro Yamada Tracev((stderr, "inflate: reset\n")); 127221b1638SMasahiro Yamada return Z_OK; 128221b1638SMasahiro Yamada } 129221b1638SMasahiro Yamada 130*fd39217aSManish Pandey int ZEXPORT inflateReset(z_streamp strm) { 131221b1638SMasahiro Yamada struct inflate_state FAR *state; 132221b1638SMasahiro Yamada 133221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 134221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 135221b1638SMasahiro Yamada state->wsize = 0; 136221b1638SMasahiro Yamada state->whave = 0; 137221b1638SMasahiro Yamada state->wnext = 0; 138221b1638SMasahiro Yamada return inflateResetKeep(strm); 139221b1638SMasahiro Yamada } 140221b1638SMasahiro Yamada 141*fd39217aSManish Pandey int ZEXPORT inflateReset2(z_streamp strm, int windowBits) { 142221b1638SMasahiro Yamada int wrap; 143221b1638SMasahiro Yamada struct inflate_state FAR *state; 144221b1638SMasahiro Yamada 145221b1638SMasahiro Yamada /* get the state */ 146221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 147221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 148221b1638SMasahiro Yamada 149221b1638SMasahiro Yamada /* extract wrap request from windowBits parameter */ 150221b1638SMasahiro Yamada if (windowBits < 0) { 151a194255dSDaniel Boulby if (windowBits < -15) 152a194255dSDaniel Boulby return Z_STREAM_ERROR; 153221b1638SMasahiro Yamada wrap = 0; 154221b1638SMasahiro Yamada windowBits = -windowBits; 155221b1638SMasahiro Yamada } 156221b1638SMasahiro Yamada else { 157221b1638SMasahiro Yamada wrap = (windowBits >> 4) + 5; 158221b1638SMasahiro Yamada #ifdef GUNZIP 159221b1638SMasahiro Yamada if (windowBits < 48) 160221b1638SMasahiro Yamada windowBits &= 15; 161221b1638SMasahiro Yamada #endif 162221b1638SMasahiro Yamada } 163221b1638SMasahiro Yamada 164221b1638SMasahiro Yamada /* set number of window bits, free window if different */ 165221b1638SMasahiro Yamada if (windowBits && (windowBits < 8 || windowBits > 15)) 166221b1638SMasahiro Yamada return Z_STREAM_ERROR; 167221b1638SMasahiro Yamada if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { 168221b1638SMasahiro Yamada ZFREE(strm, state->window); 169221b1638SMasahiro Yamada state->window = Z_NULL; 170221b1638SMasahiro Yamada } 171221b1638SMasahiro Yamada 172221b1638SMasahiro Yamada /* update state and reset the rest of it */ 173221b1638SMasahiro Yamada state->wrap = wrap; 174221b1638SMasahiro Yamada state->wbits = (unsigned)windowBits; 175221b1638SMasahiro Yamada return inflateReset(strm); 176221b1638SMasahiro Yamada } 177221b1638SMasahiro Yamada 178*fd39217aSManish Pandey int ZEXPORT inflateInit2_(z_streamp strm, int windowBits, 179*fd39217aSManish Pandey const char *version, int stream_size) { 180221b1638SMasahiro Yamada int ret; 181221b1638SMasahiro Yamada struct inflate_state FAR *state; 182221b1638SMasahiro Yamada 183221b1638SMasahiro Yamada if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 184221b1638SMasahiro Yamada stream_size != (int)(sizeof(z_stream))) 185221b1638SMasahiro Yamada return Z_VERSION_ERROR; 186221b1638SMasahiro Yamada if (strm == Z_NULL) return Z_STREAM_ERROR; 187221b1638SMasahiro Yamada strm->msg = Z_NULL; /* in case we return an error */ 188221b1638SMasahiro Yamada if (strm->zalloc == (alloc_func)0) { 189221b1638SMasahiro Yamada #ifdef Z_SOLO 190221b1638SMasahiro Yamada return Z_STREAM_ERROR; 191221b1638SMasahiro Yamada #else 192221b1638SMasahiro Yamada strm->zalloc = zcalloc; 193221b1638SMasahiro Yamada strm->opaque = (voidpf)0; 194221b1638SMasahiro Yamada #endif 195221b1638SMasahiro Yamada } 196221b1638SMasahiro Yamada if (strm->zfree == (free_func)0) 197221b1638SMasahiro Yamada #ifdef Z_SOLO 198221b1638SMasahiro Yamada return Z_STREAM_ERROR; 199221b1638SMasahiro Yamada #else 200221b1638SMasahiro Yamada strm->zfree = zcfree; 201221b1638SMasahiro Yamada #endif 202221b1638SMasahiro Yamada state = (struct inflate_state FAR *) 203221b1638SMasahiro Yamada ZALLOC(strm, 1, sizeof(struct inflate_state)); 204221b1638SMasahiro Yamada if (state == Z_NULL) return Z_MEM_ERROR; 205221b1638SMasahiro Yamada Tracev((stderr, "inflate: allocated\n")); 206221b1638SMasahiro Yamada strm->state = (struct internal_state FAR *)state; 207221b1638SMasahiro Yamada state->strm = strm; 208221b1638SMasahiro Yamada state->window = Z_NULL; 209221b1638SMasahiro Yamada state->mode = HEAD; /* to pass state test in inflateReset2() */ 210221b1638SMasahiro Yamada ret = inflateReset2(strm, windowBits); 211221b1638SMasahiro Yamada if (ret != Z_OK) { 212221b1638SMasahiro Yamada ZFREE(strm, state); 213221b1638SMasahiro Yamada strm->state = Z_NULL; 214221b1638SMasahiro Yamada } 215221b1638SMasahiro Yamada return ret; 216221b1638SMasahiro Yamada } 217221b1638SMasahiro Yamada 218*fd39217aSManish Pandey int ZEXPORT inflateInit_(z_streamp strm, const char *version, 219*fd39217aSManish Pandey int stream_size) { 220221b1638SMasahiro Yamada return inflateInit2_(strm, DEF_WBITS, version, stream_size); 221221b1638SMasahiro Yamada } 222221b1638SMasahiro Yamada 223*fd39217aSManish Pandey int ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { 224221b1638SMasahiro Yamada struct inflate_state FAR *state; 225221b1638SMasahiro Yamada 226221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 227*fd39217aSManish Pandey if (bits == 0) 228*fd39217aSManish Pandey return Z_OK; 229221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 230221b1638SMasahiro Yamada if (bits < 0) { 231221b1638SMasahiro Yamada state->hold = 0; 232221b1638SMasahiro Yamada state->bits = 0; 233221b1638SMasahiro Yamada return Z_OK; 234221b1638SMasahiro Yamada } 235221b1638SMasahiro Yamada if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; 236221b1638SMasahiro Yamada value &= (1L << bits) - 1; 237221b1638SMasahiro Yamada state->hold += (unsigned)value << state->bits; 238221b1638SMasahiro Yamada state->bits += (uInt)bits; 239221b1638SMasahiro Yamada return Z_OK; 240221b1638SMasahiro Yamada } 241221b1638SMasahiro Yamada 242221b1638SMasahiro Yamada /* 243221b1638SMasahiro Yamada Return state with length and distance decoding tables and index sizes set to 244221b1638SMasahiro Yamada fixed code decoding. Normally this returns fixed tables from inffixed.h. 245221b1638SMasahiro Yamada If BUILDFIXED is defined, then instead this routine builds the tables the 246221b1638SMasahiro Yamada first time it's called, and returns those tables the first time and 247221b1638SMasahiro Yamada thereafter. This reduces the size of the code by about 2K bytes, in 248221b1638SMasahiro Yamada exchange for a little execution time. However, BUILDFIXED should not be 249221b1638SMasahiro Yamada used for threaded applications, since the rewriting of the tables and virgin 250221b1638SMasahiro Yamada may not be thread-safe. 251221b1638SMasahiro Yamada */ 252*fd39217aSManish Pandey local void fixedtables(struct inflate_state FAR *state) { 253221b1638SMasahiro Yamada #ifdef BUILDFIXED 254221b1638SMasahiro Yamada static int virgin = 1; 255221b1638SMasahiro Yamada static code *lenfix, *distfix; 256221b1638SMasahiro Yamada static code fixed[544]; 257221b1638SMasahiro Yamada 258221b1638SMasahiro Yamada /* build fixed huffman tables if first call (may not be thread safe) */ 259221b1638SMasahiro Yamada if (virgin) { 260221b1638SMasahiro Yamada unsigned sym, bits; 261221b1638SMasahiro Yamada static code *next; 262221b1638SMasahiro Yamada 263221b1638SMasahiro Yamada /* literal/length table */ 264221b1638SMasahiro Yamada sym = 0; 265221b1638SMasahiro Yamada while (sym < 144) state->lens[sym++] = 8; 266221b1638SMasahiro Yamada while (sym < 256) state->lens[sym++] = 9; 267221b1638SMasahiro Yamada while (sym < 280) state->lens[sym++] = 7; 268221b1638SMasahiro Yamada while (sym < 288) state->lens[sym++] = 8; 269221b1638SMasahiro Yamada next = fixed; 270221b1638SMasahiro Yamada lenfix = next; 271221b1638SMasahiro Yamada bits = 9; 272221b1638SMasahiro Yamada inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); 273221b1638SMasahiro Yamada 274221b1638SMasahiro Yamada /* distance table */ 275221b1638SMasahiro Yamada sym = 0; 276221b1638SMasahiro Yamada while (sym < 32) state->lens[sym++] = 5; 277221b1638SMasahiro Yamada distfix = next; 278221b1638SMasahiro Yamada bits = 5; 279221b1638SMasahiro Yamada inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); 280221b1638SMasahiro Yamada 281221b1638SMasahiro Yamada /* do this just once */ 282221b1638SMasahiro Yamada virgin = 0; 283221b1638SMasahiro Yamada } 284221b1638SMasahiro Yamada #else /* !BUILDFIXED */ 285221b1638SMasahiro Yamada # include "inffixed.h" 286221b1638SMasahiro Yamada #endif /* BUILDFIXED */ 287221b1638SMasahiro Yamada state->lencode = lenfix; 288221b1638SMasahiro Yamada state->lenbits = 9; 289221b1638SMasahiro Yamada state->distcode = distfix; 290221b1638SMasahiro Yamada state->distbits = 5; 291221b1638SMasahiro Yamada } 292221b1638SMasahiro Yamada 293221b1638SMasahiro Yamada #ifdef MAKEFIXED 294221b1638SMasahiro Yamada #include <stdio.h> 295221b1638SMasahiro Yamada 296221b1638SMasahiro Yamada /* 297221b1638SMasahiro Yamada Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also 298221b1638SMasahiro Yamada defines BUILDFIXED, so the tables are built on the fly. makefixed() writes 299221b1638SMasahiro Yamada those tables to stdout, which would be piped to inffixed.h. A small program 300221b1638SMasahiro Yamada can simply call makefixed to do this: 301221b1638SMasahiro Yamada 302221b1638SMasahiro Yamada void makefixed(void); 303221b1638SMasahiro Yamada 304221b1638SMasahiro Yamada int main(void) 305221b1638SMasahiro Yamada { 306221b1638SMasahiro Yamada makefixed(); 307221b1638SMasahiro Yamada return 0; 308221b1638SMasahiro Yamada } 309221b1638SMasahiro Yamada 310221b1638SMasahiro Yamada Then that can be linked with zlib built with MAKEFIXED defined and run: 311221b1638SMasahiro Yamada 312221b1638SMasahiro Yamada a.out > inffixed.h 313221b1638SMasahiro Yamada */ 3142535e204SElyes Haouas void makefixed(void) 315221b1638SMasahiro Yamada { 316221b1638SMasahiro Yamada unsigned low, size; 317221b1638SMasahiro Yamada struct inflate_state state; 318221b1638SMasahiro Yamada 319221b1638SMasahiro Yamada fixedtables(&state); 320221b1638SMasahiro Yamada puts(" /* inffixed.h -- table for decoding fixed codes"); 321221b1638SMasahiro Yamada puts(" * Generated automatically by makefixed()."); 322221b1638SMasahiro Yamada puts(" */"); 323221b1638SMasahiro Yamada puts(""); 324221b1638SMasahiro Yamada puts(" /* WARNING: this file should *not* be used by applications."); 325221b1638SMasahiro Yamada puts(" It is part of the implementation of this library and is"); 326221b1638SMasahiro Yamada puts(" subject to change. Applications should only use zlib.h."); 327221b1638SMasahiro Yamada puts(" */"); 328221b1638SMasahiro Yamada puts(""); 329221b1638SMasahiro Yamada size = 1U << 9; 330221b1638SMasahiro Yamada printf(" static const code lenfix[%u] = {", size); 331221b1638SMasahiro Yamada low = 0; 332221b1638SMasahiro Yamada for (;;) { 333221b1638SMasahiro Yamada if ((low % 7) == 0) printf("\n "); 334221b1638SMasahiro Yamada printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, 335221b1638SMasahiro Yamada state.lencode[low].bits, state.lencode[low].val); 336221b1638SMasahiro Yamada if (++low == size) break; 337221b1638SMasahiro Yamada putchar(','); 338221b1638SMasahiro Yamada } 339221b1638SMasahiro Yamada puts("\n };"); 340221b1638SMasahiro Yamada size = 1U << 5; 341221b1638SMasahiro Yamada printf("\n static const code distfix[%u] = {", size); 342221b1638SMasahiro Yamada low = 0; 343221b1638SMasahiro Yamada for (;;) { 344221b1638SMasahiro Yamada if ((low % 6) == 0) printf("\n "); 345221b1638SMasahiro Yamada printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, 346221b1638SMasahiro Yamada state.distcode[low].val); 347221b1638SMasahiro Yamada if (++low == size) break; 348221b1638SMasahiro Yamada putchar(','); 349221b1638SMasahiro Yamada } 350221b1638SMasahiro Yamada puts("\n };"); 351221b1638SMasahiro Yamada } 352221b1638SMasahiro Yamada #endif /* MAKEFIXED */ 353221b1638SMasahiro Yamada 354221b1638SMasahiro Yamada /* 355221b1638SMasahiro Yamada Update the window with the last wsize (normally 32K) bytes written before 356221b1638SMasahiro Yamada returning. If window does not exist yet, create it. This is only called 357221b1638SMasahiro Yamada when a window is already in use, or when output has been written during this 358221b1638SMasahiro Yamada inflate call, but the end of the deflate stream has not been reached yet. 359221b1638SMasahiro Yamada It is also called to create a window for dictionary data when a dictionary 360221b1638SMasahiro Yamada is loaded. 361221b1638SMasahiro Yamada 362221b1638SMasahiro Yamada Providing output buffers larger than 32K to inflate() should provide a speed 363221b1638SMasahiro Yamada advantage, since only the last 32K of output is copied to the sliding window 364221b1638SMasahiro Yamada upon return from inflate(), and since all distances after the first 32K of 365221b1638SMasahiro Yamada output will fall in the output data, making match copies simpler and faster. 366221b1638SMasahiro Yamada The advantage may be dependent on the size of the processor's data caches. 367221b1638SMasahiro Yamada */ 368*fd39217aSManish Pandey local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) { 369221b1638SMasahiro Yamada struct inflate_state FAR *state; 370221b1638SMasahiro Yamada unsigned dist; 371221b1638SMasahiro Yamada 372221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 373221b1638SMasahiro Yamada 374221b1638SMasahiro Yamada /* if it hasn't been done already, allocate space for the window */ 375221b1638SMasahiro Yamada if (state->window == Z_NULL) { 376221b1638SMasahiro Yamada state->window = (unsigned char FAR *) 377221b1638SMasahiro Yamada ZALLOC(strm, 1U << state->wbits, 378221b1638SMasahiro Yamada sizeof(unsigned char)); 379221b1638SMasahiro Yamada if (state->window == Z_NULL) return 1; 380221b1638SMasahiro Yamada } 381221b1638SMasahiro Yamada 382221b1638SMasahiro Yamada /* if window not in use yet, initialize */ 383221b1638SMasahiro Yamada if (state->wsize == 0) { 384221b1638SMasahiro Yamada state->wsize = 1U << state->wbits; 385221b1638SMasahiro Yamada state->wnext = 0; 386221b1638SMasahiro Yamada state->whave = 0; 387221b1638SMasahiro Yamada } 388221b1638SMasahiro Yamada 389221b1638SMasahiro Yamada /* copy state->wsize or less output bytes into the circular window */ 390221b1638SMasahiro Yamada if (copy >= state->wsize) { 391221b1638SMasahiro Yamada zmemcpy(state->window, end - state->wsize, state->wsize); 392221b1638SMasahiro Yamada state->wnext = 0; 393221b1638SMasahiro Yamada state->whave = state->wsize; 394221b1638SMasahiro Yamada } 395221b1638SMasahiro Yamada else { 396221b1638SMasahiro Yamada dist = state->wsize - state->wnext; 397221b1638SMasahiro Yamada if (dist > copy) dist = copy; 398221b1638SMasahiro Yamada zmemcpy(state->window + state->wnext, end - copy, dist); 399221b1638SMasahiro Yamada copy -= dist; 400221b1638SMasahiro Yamada if (copy) { 401221b1638SMasahiro Yamada zmemcpy(state->window, end - copy, copy); 402221b1638SMasahiro Yamada state->wnext = copy; 403221b1638SMasahiro Yamada state->whave = state->wsize; 404221b1638SMasahiro Yamada } 405221b1638SMasahiro Yamada else { 406221b1638SMasahiro Yamada state->wnext += dist; 407221b1638SMasahiro Yamada if (state->wnext == state->wsize) state->wnext = 0; 408221b1638SMasahiro Yamada if (state->whave < state->wsize) state->whave += dist; 409221b1638SMasahiro Yamada } 410221b1638SMasahiro Yamada } 411221b1638SMasahiro Yamada return 0; 412221b1638SMasahiro Yamada } 413221b1638SMasahiro Yamada 414221b1638SMasahiro Yamada /* Macros for inflate(): */ 415221b1638SMasahiro Yamada 416221b1638SMasahiro Yamada /* check function to use adler32() for zlib or crc32() for gzip */ 417221b1638SMasahiro Yamada #ifdef GUNZIP 418a194255dSDaniel Boulby # define UPDATE_CHECK(check, buf, len) \ 419221b1638SMasahiro Yamada (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) 420221b1638SMasahiro Yamada #else 421a194255dSDaniel Boulby # define UPDATE_CHECK(check, buf, len) adler32(check, buf, len) 422221b1638SMasahiro Yamada #endif 423221b1638SMasahiro Yamada 424221b1638SMasahiro Yamada /* check macros for header crc */ 425221b1638SMasahiro Yamada #ifdef GUNZIP 426221b1638SMasahiro Yamada # define CRC2(check, word) \ 427221b1638SMasahiro Yamada do { \ 428221b1638SMasahiro Yamada hbuf[0] = (unsigned char)(word); \ 429221b1638SMasahiro Yamada hbuf[1] = (unsigned char)((word) >> 8); \ 430221b1638SMasahiro Yamada check = crc32(check, hbuf, 2); \ 431221b1638SMasahiro Yamada } while (0) 432221b1638SMasahiro Yamada 433221b1638SMasahiro Yamada # define CRC4(check, word) \ 434221b1638SMasahiro Yamada do { \ 435221b1638SMasahiro Yamada hbuf[0] = (unsigned char)(word); \ 436221b1638SMasahiro Yamada hbuf[1] = (unsigned char)((word) >> 8); \ 437221b1638SMasahiro Yamada hbuf[2] = (unsigned char)((word) >> 16); \ 438221b1638SMasahiro Yamada hbuf[3] = (unsigned char)((word) >> 24); \ 439221b1638SMasahiro Yamada check = crc32(check, hbuf, 4); \ 440221b1638SMasahiro Yamada } while (0) 441221b1638SMasahiro Yamada #endif 442221b1638SMasahiro Yamada 443221b1638SMasahiro Yamada /* Load registers with state in inflate() for speed */ 444221b1638SMasahiro Yamada #define LOAD() \ 445221b1638SMasahiro Yamada do { \ 446221b1638SMasahiro Yamada put = strm->next_out; \ 447221b1638SMasahiro Yamada left = strm->avail_out; \ 448221b1638SMasahiro Yamada next = strm->next_in; \ 449221b1638SMasahiro Yamada have = strm->avail_in; \ 450221b1638SMasahiro Yamada hold = state->hold; \ 451221b1638SMasahiro Yamada bits = state->bits; \ 452221b1638SMasahiro Yamada } while (0) 453221b1638SMasahiro Yamada 454221b1638SMasahiro Yamada /* Restore state from registers in inflate() */ 455221b1638SMasahiro Yamada #define RESTORE() \ 456221b1638SMasahiro Yamada do { \ 457221b1638SMasahiro Yamada strm->next_out = put; \ 458221b1638SMasahiro Yamada strm->avail_out = left; \ 459221b1638SMasahiro Yamada strm->next_in = next; \ 460221b1638SMasahiro Yamada strm->avail_in = have; \ 461221b1638SMasahiro Yamada state->hold = hold; \ 462221b1638SMasahiro Yamada state->bits = bits; \ 463221b1638SMasahiro Yamada } while (0) 464221b1638SMasahiro Yamada 465221b1638SMasahiro Yamada /* Clear the input bit accumulator */ 466221b1638SMasahiro Yamada #define INITBITS() \ 467221b1638SMasahiro Yamada do { \ 468221b1638SMasahiro Yamada hold = 0; \ 469221b1638SMasahiro Yamada bits = 0; \ 470221b1638SMasahiro Yamada } while (0) 471221b1638SMasahiro Yamada 472221b1638SMasahiro Yamada /* Get a byte of input into the bit accumulator, or return from inflate() 473221b1638SMasahiro Yamada if there is no input available. */ 474221b1638SMasahiro Yamada #define PULLBYTE() \ 475221b1638SMasahiro Yamada do { \ 476221b1638SMasahiro Yamada if (have == 0) goto inf_leave; \ 477221b1638SMasahiro Yamada have--; \ 478221b1638SMasahiro Yamada hold += (unsigned long)(*next++) << bits; \ 479221b1638SMasahiro Yamada bits += 8; \ 480221b1638SMasahiro Yamada } while (0) 481221b1638SMasahiro Yamada 482221b1638SMasahiro Yamada /* Assure that there are at least n bits in the bit accumulator. If there is 483221b1638SMasahiro Yamada not enough available input to do that, then return from inflate(). */ 484221b1638SMasahiro Yamada #define NEEDBITS(n) \ 485221b1638SMasahiro Yamada do { \ 486221b1638SMasahiro Yamada while (bits < (unsigned)(n)) \ 487221b1638SMasahiro Yamada PULLBYTE(); \ 488221b1638SMasahiro Yamada } while (0) 489221b1638SMasahiro Yamada 490221b1638SMasahiro Yamada /* Return the low n bits of the bit accumulator (n < 16) */ 491221b1638SMasahiro Yamada #define BITS(n) \ 492221b1638SMasahiro Yamada ((unsigned)hold & ((1U << (n)) - 1)) 493221b1638SMasahiro Yamada 494221b1638SMasahiro Yamada /* Remove n bits from the bit accumulator */ 495221b1638SMasahiro Yamada #define DROPBITS(n) \ 496221b1638SMasahiro Yamada do { \ 497221b1638SMasahiro Yamada hold >>= (n); \ 498221b1638SMasahiro Yamada bits -= (unsigned)(n); \ 499221b1638SMasahiro Yamada } while (0) 500221b1638SMasahiro Yamada 501221b1638SMasahiro Yamada /* Remove zero to seven bits as needed to go to a byte boundary */ 502221b1638SMasahiro Yamada #define BYTEBITS() \ 503221b1638SMasahiro Yamada do { \ 504221b1638SMasahiro Yamada hold >>= bits & 7; \ 505221b1638SMasahiro Yamada bits -= bits & 7; \ 506221b1638SMasahiro Yamada } while (0) 507221b1638SMasahiro Yamada 508221b1638SMasahiro Yamada /* 509221b1638SMasahiro Yamada inflate() uses a state machine to process as much input data and generate as 510221b1638SMasahiro Yamada much output data as possible before returning. The state machine is 511221b1638SMasahiro Yamada structured roughly as follows: 512221b1638SMasahiro Yamada 513221b1638SMasahiro Yamada for (;;) switch (state) { 514221b1638SMasahiro Yamada ... 515221b1638SMasahiro Yamada case STATEn: 516221b1638SMasahiro Yamada if (not enough input data or output space to make progress) 517221b1638SMasahiro Yamada return; 518221b1638SMasahiro Yamada ... make progress ... 519221b1638SMasahiro Yamada state = STATEm; 520221b1638SMasahiro Yamada break; 521221b1638SMasahiro Yamada ... 522221b1638SMasahiro Yamada } 523221b1638SMasahiro Yamada 524221b1638SMasahiro Yamada so when inflate() is called again, the same case is attempted again, and 525221b1638SMasahiro Yamada if the appropriate resources are provided, the machine proceeds to the 526221b1638SMasahiro Yamada next state. The NEEDBITS() macro is usually the way the state evaluates 527221b1638SMasahiro Yamada whether it can proceed or should return. NEEDBITS() does the return if 528221b1638SMasahiro Yamada the requested bits are not available. The typical use of the BITS macros 529221b1638SMasahiro Yamada is: 530221b1638SMasahiro Yamada 531221b1638SMasahiro Yamada NEEDBITS(n); 532221b1638SMasahiro Yamada ... do something with BITS(n) ... 533221b1638SMasahiro Yamada DROPBITS(n); 534221b1638SMasahiro Yamada 535221b1638SMasahiro Yamada where NEEDBITS(n) either returns from inflate() if there isn't enough 536221b1638SMasahiro Yamada input left to load n bits into the accumulator, or it continues. BITS(n) 537221b1638SMasahiro Yamada gives the low n bits in the accumulator. When done, DROPBITS(n) drops 538221b1638SMasahiro Yamada the low n bits off the accumulator. INITBITS() clears the accumulator 539221b1638SMasahiro Yamada and sets the number of available bits to zero. BYTEBITS() discards just 540221b1638SMasahiro Yamada enough bits to put the accumulator on a byte boundary. After BYTEBITS() 541221b1638SMasahiro Yamada and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. 542221b1638SMasahiro Yamada 543221b1638SMasahiro Yamada NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return 544221b1638SMasahiro Yamada if there is no input available. The decoding of variable length codes uses 545221b1638SMasahiro Yamada PULLBYTE() directly in order to pull just enough bytes to decode the next 546221b1638SMasahiro Yamada code, and no more. 547221b1638SMasahiro Yamada 548221b1638SMasahiro Yamada Some states loop until they get enough input, making sure that enough 549221b1638SMasahiro Yamada state information is maintained to continue the loop where it left off 550221b1638SMasahiro Yamada if NEEDBITS() returns in the loop. For example, want, need, and keep 551221b1638SMasahiro Yamada would all have to actually be part of the saved state in case NEEDBITS() 552221b1638SMasahiro Yamada returns: 553221b1638SMasahiro Yamada 554221b1638SMasahiro Yamada case STATEw: 555221b1638SMasahiro Yamada while (want < need) { 556221b1638SMasahiro Yamada NEEDBITS(n); 557221b1638SMasahiro Yamada keep[want++] = BITS(n); 558221b1638SMasahiro Yamada DROPBITS(n); 559221b1638SMasahiro Yamada } 560221b1638SMasahiro Yamada state = STATEx; 561221b1638SMasahiro Yamada case STATEx: 562221b1638SMasahiro Yamada 563221b1638SMasahiro Yamada As shown above, if the next state is also the next case, then the break 564221b1638SMasahiro Yamada is omitted. 565221b1638SMasahiro Yamada 566221b1638SMasahiro Yamada A state may also return if there is not enough output space available to 567221b1638SMasahiro Yamada complete that state. Those states are copying stored data, writing a 568221b1638SMasahiro Yamada literal byte, and copying a matching string. 569221b1638SMasahiro Yamada 570221b1638SMasahiro Yamada When returning, a "goto inf_leave" is used to update the total counters, 571221b1638SMasahiro Yamada update the check value, and determine whether any progress has been made 572221b1638SMasahiro Yamada during that inflate() call in order to return the proper return code. 573221b1638SMasahiro Yamada Progress is defined as a change in either strm->avail_in or strm->avail_out. 574221b1638SMasahiro Yamada When there is a window, goto inf_leave will update the window with the last 575221b1638SMasahiro Yamada output written. If a goto inf_leave occurs in the middle of decompression 576221b1638SMasahiro Yamada and there is no window currently, goto inf_leave will create one and copy 577221b1638SMasahiro Yamada output to the window for the next call of inflate(). 578221b1638SMasahiro Yamada 579221b1638SMasahiro Yamada In this implementation, the flush parameter of inflate() only affects the 580221b1638SMasahiro Yamada return code (per zlib.h). inflate() always writes as much as possible to 581221b1638SMasahiro Yamada strm->next_out, given the space available and the provided input--the effect 582221b1638SMasahiro Yamada documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers 583221b1638SMasahiro Yamada the allocation of and copying into a sliding window until necessary, which 584221b1638SMasahiro Yamada provides the effect documented in zlib.h for Z_FINISH when the entire input 585221b1638SMasahiro Yamada stream available. So the only thing the flush parameter actually does is: 586221b1638SMasahiro Yamada when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it 587221b1638SMasahiro Yamada will return Z_BUF_ERROR if it has not reached the end of the stream. 588221b1638SMasahiro Yamada */ 589221b1638SMasahiro Yamada 590*fd39217aSManish Pandey int ZEXPORT inflate(z_streamp strm, int flush) { 591221b1638SMasahiro Yamada struct inflate_state FAR *state; 592221b1638SMasahiro Yamada z_const unsigned char FAR *next; /* next input */ 593221b1638SMasahiro Yamada unsigned char FAR *put; /* next output */ 594221b1638SMasahiro Yamada unsigned have, left; /* available input and output */ 595221b1638SMasahiro Yamada unsigned long hold; /* bit buffer */ 596221b1638SMasahiro Yamada unsigned bits; /* bits in bit buffer */ 597221b1638SMasahiro Yamada unsigned in, out; /* save starting available input and output */ 598221b1638SMasahiro Yamada unsigned copy; /* number of stored or match bytes to copy */ 599221b1638SMasahiro Yamada unsigned char FAR *from; /* where to copy match bytes from */ 600221b1638SMasahiro Yamada code here; /* current decoding table entry */ 601221b1638SMasahiro Yamada code last; /* parent table entry */ 602221b1638SMasahiro Yamada unsigned len; /* length to copy for repeats, bits to drop */ 603221b1638SMasahiro Yamada int ret; /* return code */ 604221b1638SMasahiro Yamada #ifdef GUNZIP 605221b1638SMasahiro Yamada unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ 606221b1638SMasahiro Yamada #endif 607221b1638SMasahiro Yamada static const unsigned short order[19] = /* permutation of code lengths */ 608221b1638SMasahiro Yamada {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 609221b1638SMasahiro Yamada 610221b1638SMasahiro Yamada if (inflateStateCheck(strm) || strm->next_out == Z_NULL || 611221b1638SMasahiro Yamada (strm->next_in == Z_NULL && strm->avail_in != 0)) 612221b1638SMasahiro Yamada return Z_STREAM_ERROR; 613221b1638SMasahiro Yamada 614221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 615221b1638SMasahiro Yamada if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ 616221b1638SMasahiro Yamada LOAD(); 617221b1638SMasahiro Yamada in = have; 618221b1638SMasahiro Yamada out = left; 619221b1638SMasahiro Yamada ret = Z_OK; 620221b1638SMasahiro Yamada for (;;) 621221b1638SMasahiro Yamada switch (state->mode) { 622221b1638SMasahiro Yamada case HEAD: 623221b1638SMasahiro Yamada if (state->wrap == 0) { 624221b1638SMasahiro Yamada state->mode = TYPEDO; 625221b1638SMasahiro Yamada break; 626221b1638SMasahiro Yamada } 627221b1638SMasahiro Yamada NEEDBITS(16); 628221b1638SMasahiro Yamada #ifdef GUNZIP 629221b1638SMasahiro Yamada if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ 630221b1638SMasahiro Yamada if (state->wbits == 0) 631221b1638SMasahiro Yamada state->wbits = 15; 632221b1638SMasahiro Yamada state->check = crc32(0L, Z_NULL, 0); 633221b1638SMasahiro Yamada CRC2(state->check, hold); 634221b1638SMasahiro Yamada INITBITS(); 635221b1638SMasahiro Yamada state->mode = FLAGS; 636221b1638SMasahiro Yamada break; 637221b1638SMasahiro Yamada } 638221b1638SMasahiro Yamada if (state->head != Z_NULL) 639221b1638SMasahiro Yamada state->head->done = -1; 640221b1638SMasahiro Yamada if (!(state->wrap & 1) || /* check if zlib header allowed */ 641221b1638SMasahiro Yamada #else 642221b1638SMasahiro Yamada if ( 643221b1638SMasahiro Yamada #endif 644221b1638SMasahiro Yamada ((BITS(8) << 8) + (hold >> 8)) % 31) { 645221b1638SMasahiro Yamada strm->msg = (char *)"incorrect header check"; 646221b1638SMasahiro Yamada state->mode = BAD; 647221b1638SMasahiro Yamada break; 648221b1638SMasahiro Yamada } 649221b1638SMasahiro Yamada if (BITS(4) != Z_DEFLATED) { 650221b1638SMasahiro Yamada strm->msg = (char *)"unknown compression method"; 651221b1638SMasahiro Yamada state->mode = BAD; 652221b1638SMasahiro Yamada break; 653221b1638SMasahiro Yamada } 654221b1638SMasahiro Yamada DROPBITS(4); 655221b1638SMasahiro Yamada len = BITS(4) + 8; 656221b1638SMasahiro Yamada if (state->wbits == 0) 657221b1638SMasahiro Yamada state->wbits = len; 658221b1638SMasahiro Yamada if (len > 15 || len > state->wbits) { 659221b1638SMasahiro Yamada strm->msg = (char *)"invalid window size"; 660221b1638SMasahiro Yamada state->mode = BAD; 661221b1638SMasahiro Yamada break; 662221b1638SMasahiro Yamada } 663221b1638SMasahiro Yamada state->dmax = 1U << len; 664a194255dSDaniel Boulby state->flags = 0; /* indicate zlib header */ 665221b1638SMasahiro Yamada Tracev((stderr, "inflate: zlib header ok\n")); 666221b1638SMasahiro Yamada strm->adler = state->check = adler32(0L, Z_NULL, 0); 667221b1638SMasahiro Yamada state->mode = hold & 0x200 ? DICTID : TYPE; 668221b1638SMasahiro Yamada INITBITS(); 669221b1638SMasahiro Yamada break; 670221b1638SMasahiro Yamada #ifdef GUNZIP 671221b1638SMasahiro Yamada case FLAGS: 672221b1638SMasahiro Yamada NEEDBITS(16); 673221b1638SMasahiro Yamada state->flags = (int)(hold); 674221b1638SMasahiro Yamada if ((state->flags & 0xff) != Z_DEFLATED) { 675221b1638SMasahiro Yamada strm->msg = (char *)"unknown compression method"; 676221b1638SMasahiro Yamada state->mode = BAD; 677221b1638SMasahiro Yamada break; 678221b1638SMasahiro Yamada } 679221b1638SMasahiro Yamada if (state->flags & 0xe000) { 680221b1638SMasahiro Yamada strm->msg = (char *)"unknown header flags set"; 681221b1638SMasahiro Yamada state->mode = BAD; 682221b1638SMasahiro Yamada break; 683221b1638SMasahiro Yamada } 684221b1638SMasahiro Yamada if (state->head != Z_NULL) 685221b1638SMasahiro Yamada state->head->text = (int)((hold >> 8) & 1); 686221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 687221b1638SMasahiro Yamada CRC2(state->check, hold); 688221b1638SMasahiro Yamada INITBITS(); 689221b1638SMasahiro Yamada state->mode = TIME; 690a194255dSDaniel Boulby /* fallthrough */ 691221b1638SMasahiro Yamada case TIME: 692221b1638SMasahiro Yamada NEEDBITS(32); 693221b1638SMasahiro Yamada if (state->head != Z_NULL) 694221b1638SMasahiro Yamada state->head->time = hold; 695221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 696221b1638SMasahiro Yamada CRC4(state->check, hold); 697221b1638SMasahiro Yamada INITBITS(); 698221b1638SMasahiro Yamada state->mode = OS; 699a194255dSDaniel Boulby /* fallthrough */ 700221b1638SMasahiro Yamada case OS: 701221b1638SMasahiro Yamada NEEDBITS(16); 702221b1638SMasahiro Yamada if (state->head != Z_NULL) { 703221b1638SMasahiro Yamada state->head->xflags = (int)(hold & 0xff); 704221b1638SMasahiro Yamada state->head->os = (int)(hold >> 8); 705221b1638SMasahiro Yamada } 706221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 707221b1638SMasahiro Yamada CRC2(state->check, hold); 708221b1638SMasahiro Yamada INITBITS(); 709221b1638SMasahiro Yamada state->mode = EXLEN; 710a194255dSDaniel Boulby /* fallthrough */ 711221b1638SMasahiro Yamada case EXLEN: 712221b1638SMasahiro Yamada if (state->flags & 0x0400) { 713221b1638SMasahiro Yamada NEEDBITS(16); 714221b1638SMasahiro Yamada state->length = (unsigned)(hold); 715221b1638SMasahiro Yamada if (state->head != Z_NULL) 716221b1638SMasahiro Yamada state->head->extra_len = (unsigned)hold; 717221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 718221b1638SMasahiro Yamada CRC2(state->check, hold); 719221b1638SMasahiro Yamada INITBITS(); 720221b1638SMasahiro Yamada } 721221b1638SMasahiro Yamada else if (state->head != Z_NULL) 722221b1638SMasahiro Yamada state->head->extra = Z_NULL; 723221b1638SMasahiro Yamada state->mode = EXTRA; 724a194255dSDaniel Boulby /* fallthrough */ 725221b1638SMasahiro Yamada case EXTRA: 726221b1638SMasahiro Yamada if (state->flags & 0x0400) { 727221b1638SMasahiro Yamada copy = state->length; 728221b1638SMasahiro Yamada if (copy > have) copy = have; 729221b1638SMasahiro Yamada if (copy) { 730221b1638SMasahiro Yamada if (state->head != Z_NULL && 731a194255dSDaniel Boulby state->head->extra != Z_NULL && 732a194255dSDaniel Boulby (len = state->head->extra_len - state->length) < 733a194255dSDaniel Boulby state->head->extra_max) { 734221b1638SMasahiro Yamada zmemcpy(state->head->extra + len, next, 735221b1638SMasahiro Yamada len + copy > state->head->extra_max ? 736221b1638SMasahiro Yamada state->head->extra_max - len : copy); 737221b1638SMasahiro Yamada } 738221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 739221b1638SMasahiro Yamada state->check = crc32(state->check, next, copy); 740221b1638SMasahiro Yamada have -= copy; 741221b1638SMasahiro Yamada next += copy; 742221b1638SMasahiro Yamada state->length -= copy; 743221b1638SMasahiro Yamada } 744221b1638SMasahiro Yamada if (state->length) goto inf_leave; 745221b1638SMasahiro Yamada } 746221b1638SMasahiro Yamada state->length = 0; 747221b1638SMasahiro Yamada state->mode = NAME; 748a194255dSDaniel Boulby /* fallthrough */ 749221b1638SMasahiro Yamada case NAME: 750221b1638SMasahiro Yamada if (state->flags & 0x0800) { 751221b1638SMasahiro Yamada if (have == 0) goto inf_leave; 752221b1638SMasahiro Yamada copy = 0; 753221b1638SMasahiro Yamada do { 754221b1638SMasahiro Yamada len = (unsigned)(next[copy++]); 755221b1638SMasahiro Yamada if (state->head != Z_NULL && 756221b1638SMasahiro Yamada state->head->name != Z_NULL && 757221b1638SMasahiro Yamada state->length < state->head->name_max) 758221b1638SMasahiro Yamada state->head->name[state->length++] = (Bytef)len; 759221b1638SMasahiro Yamada } while (len && copy < have); 760221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 761221b1638SMasahiro Yamada state->check = crc32(state->check, next, copy); 762221b1638SMasahiro Yamada have -= copy; 763221b1638SMasahiro Yamada next += copy; 764221b1638SMasahiro Yamada if (len) goto inf_leave; 765221b1638SMasahiro Yamada } 766221b1638SMasahiro Yamada else if (state->head != Z_NULL) 767221b1638SMasahiro Yamada state->head->name = Z_NULL; 768221b1638SMasahiro Yamada state->length = 0; 769221b1638SMasahiro Yamada state->mode = COMMENT; 770a194255dSDaniel Boulby /* fallthrough */ 771221b1638SMasahiro Yamada case COMMENT: 772221b1638SMasahiro Yamada if (state->flags & 0x1000) { 773221b1638SMasahiro Yamada if (have == 0) goto inf_leave; 774221b1638SMasahiro Yamada copy = 0; 775221b1638SMasahiro Yamada do { 776221b1638SMasahiro Yamada len = (unsigned)(next[copy++]); 777221b1638SMasahiro Yamada if (state->head != Z_NULL && 778221b1638SMasahiro Yamada state->head->comment != Z_NULL && 779221b1638SMasahiro Yamada state->length < state->head->comm_max) 780221b1638SMasahiro Yamada state->head->comment[state->length++] = (Bytef)len; 781221b1638SMasahiro Yamada } while (len && copy < have); 782221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 783221b1638SMasahiro Yamada state->check = crc32(state->check, next, copy); 784221b1638SMasahiro Yamada have -= copy; 785221b1638SMasahiro Yamada next += copy; 786221b1638SMasahiro Yamada if (len) goto inf_leave; 787221b1638SMasahiro Yamada } 788221b1638SMasahiro Yamada else if (state->head != Z_NULL) 789221b1638SMasahiro Yamada state->head->comment = Z_NULL; 790221b1638SMasahiro Yamada state->mode = HCRC; 791a194255dSDaniel Boulby /* fallthrough */ 792221b1638SMasahiro Yamada case HCRC: 793221b1638SMasahiro Yamada if (state->flags & 0x0200) { 794221b1638SMasahiro Yamada NEEDBITS(16); 795221b1638SMasahiro Yamada if ((state->wrap & 4) && hold != (state->check & 0xffff)) { 796221b1638SMasahiro Yamada strm->msg = (char *)"header crc mismatch"; 797221b1638SMasahiro Yamada state->mode = BAD; 798221b1638SMasahiro Yamada break; 799221b1638SMasahiro Yamada } 800221b1638SMasahiro Yamada INITBITS(); 801221b1638SMasahiro Yamada } 802221b1638SMasahiro Yamada if (state->head != Z_NULL) { 803221b1638SMasahiro Yamada state->head->hcrc = (int)((state->flags >> 9) & 1); 804221b1638SMasahiro Yamada state->head->done = 1; 805221b1638SMasahiro Yamada } 806221b1638SMasahiro Yamada strm->adler = state->check = crc32(0L, Z_NULL, 0); 807221b1638SMasahiro Yamada state->mode = TYPE; 808221b1638SMasahiro Yamada break; 809221b1638SMasahiro Yamada #endif 810221b1638SMasahiro Yamada case DICTID: 811221b1638SMasahiro Yamada NEEDBITS(32); 812221b1638SMasahiro Yamada strm->adler = state->check = ZSWAP32(hold); 813221b1638SMasahiro Yamada INITBITS(); 814221b1638SMasahiro Yamada state->mode = DICT; 815a194255dSDaniel Boulby /* fallthrough */ 816221b1638SMasahiro Yamada case DICT: 817221b1638SMasahiro Yamada if (state->havedict == 0) { 818221b1638SMasahiro Yamada RESTORE(); 819221b1638SMasahiro Yamada return Z_NEED_DICT; 820221b1638SMasahiro Yamada } 821221b1638SMasahiro Yamada strm->adler = state->check = adler32(0L, Z_NULL, 0); 822221b1638SMasahiro Yamada state->mode = TYPE; 823a194255dSDaniel Boulby /* fallthrough */ 824221b1638SMasahiro Yamada case TYPE: 825221b1638SMasahiro Yamada if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; 826a194255dSDaniel Boulby /* fallthrough */ 827221b1638SMasahiro Yamada case TYPEDO: 828221b1638SMasahiro Yamada if (state->last) { 829221b1638SMasahiro Yamada BYTEBITS(); 830221b1638SMasahiro Yamada state->mode = CHECK; 831221b1638SMasahiro Yamada break; 832221b1638SMasahiro Yamada } 833221b1638SMasahiro Yamada NEEDBITS(3); 834221b1638SMasahiro Yamada state->last = BITS(1); 835221b1638SMasahiro Yamada DROPBITS(1); 836221b1638SMasahiro Yamada switch (BITS(2)) { 837221b1638SMasahiro Yamada case 0: /* stored block */ 838221b1638SMasahiro Yamada Tracev((stderr, "inflate: stored block%s\n", 839221b1638SMasahiro Yamada state->last ? " (last)" : "")); 840221b1638SMasahiro Yamada state->mode = STORED; 841221b1638SMasahiro Yamada break; 842221b1638SMasahiro Yamada case 1: /* fixed block */ 843221b1638SMasahiro Yamada fixedtables(state); 844221b1638SMasahiro Yamada Tracev((stderr, "inflate: fixed codes block%s\n", 845221b1638SMasahiro Yamada state->last ? " (last)" : "")); 846221b1638SMasahiro Yamada state->mode = LEN_; /* decode codes */ 847221b1638SMasahiro Yamada if (flush == Z_TREES) { 848221b1638SMasahiro Yamada DROPBITS(2); 849221b1638SMasahiro Yamada goto inf_leave; 850221b1638SMasahiro Yamada } 851221b1638SMasahiro Yamada break; 852221b1638SMasahiro Yamada case 2: /* dynamic block */ 853221b1638SMasahiro Yamada Tracev((stderr, "inflate: dynamic codes block%s\n", 854221b1638SMasahiro Yamada state->last ? " (last)" : "")); 855221b1638SMasahiro Yamada state->mode = TABLE; 856221b1638SMasahiro Yamada break; 857221b1638SMasahiro Yamada case 3: 858221b1638SMasahiro Yamada strm->msg = (char *)"invalid block type"; 859221b1638SMasahiro Yamada state->mode = BAD; 860221b1638SMasahiro Yamada } 861221b1638SMasahiro Yamada DROPBITS(2); 862221b1638SMasahiro Yamada break; 863221b1638SMasahiro Yamada case STORED: 864221b1638SMasahiro Yamada BYTEBITS(); /* go to byte boundary */ 865221b1638SMasahiro Yamada NEEDBITS(32); 866221b1638SMasahiro Yamada if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { 867221b1638SMasahiro Yamada strm->msg = (char *)"invalid stored block lengths"; 868221b1638SMasahiro Yamada state->mode = BAD; 869221b1638SMasahiro Yamada break; 870221b1638SMasahiro Yamada } 871221b1638SMasahiro Yamada state->length = (unsigned)hold & 0xffff; 872221b1638SMasahiro Yamada Tracev((stderr, "inflate: stored length %u\n", 873221b1638SMasahiro Yamada state->length)); 874221b1638SMasahiro Yamada INITBITS(); 875221b1638SMasahiro Yamada state->mode = COPY_; 876221b1638SMasahiro Yamada if (flush == Z_TREES) goto inf_leave; 877a194255dSDaniel Boulby /* fallthrough */ 878221b1638SMasahiro Yamada case COPY_: 879221b1638SMasahiro Yamada state->mode = COPY; 880a194255dSDaniel Boulby /* fallthrough */ 881221b1638SMasahiro Yamada case COPY: 882221b1638SMasahiro Yamada copy = state->length; 883221b1638SMasahiro Yamada if (copy) { 884221b1638SMasahiro Yamada if (copy > have) copy = have; 885221b1638SMasahiro Yamada if (copy > left) copy = left; 886221b1638SMasahiro Yamada if (copy == 0) goto inf_leave; 887221b1638SMasahiro Yamada zmemcpy(put, next, copy); 888221b1638SMasahiro Yamada have -= copy; 889221b1638SMasahiro Yamada next += copy; 890221b1638SMasahiro Yamada left -= copy; 891221b1638SMasahiro Yamada put += copy; 892221b1638SMasahiro Yamada state->length -= copy; 893221b1638SMasahiro Yamada break; 894221b1638SMasahiro Yamada } 895221b1638SMasahiro Yamada Tracev((stderr, "inflate: stored end\n")); 896221b1638SMasahiro Yamada state->mode = TYPE; 897221b1638SMasahiro Yamada break; 898221b1638SMasahiro Yamada case TABLE: 899221b1638SMasahiro Yamada NEEDBITS(14); 900221b1638SMasahiro Yamada state->nlen = BITS(5) + 257; 901221b1638SMasahiro Yamada DROPBITS(5); 902221b1638SMasahiro Yamada state->ndist = BITS(5) + 1; 903221b1638SMasahiro Yamada DROPBITS(5); 904221b1638SMasahiro Yamada state->ncode = BITS(4) + 4; 905221b1638SMasahiro Yamada DROPBITS(4); 906221b1638SMasahiro Yamada #ifndef PKZIP_BUG_WORKAROUND 907221b1638SMasahiro Yamada if (state->nlen > 286 || state->ndist > 30) { 908221b1638SMasahiro Yamada strm->msg = (char *)"too many length or distance symbols"; 909221b1638SMasahiro Yamada state->mode = BAD; 910221b1638SMasahiro Yamada break; 911221b1638SMasahiro Yamada } 912221b1638SMasahiro Yamada #endif 913221b1638SMasahiro Yamada Tracev((stderr, "inflate: table sizes ok\n")); 914221b1638SMasahiro Yamada state->have = 0; 915221b1638SMasahiro Yamada state->mode = LENLENS; 916a194255dSDaniel Boulby /* fallthrough */ 917221b1638SMasahiro Yamada case LENLENS: 918221b1638SMasahiro Yamada while (state->have < state->ncode) { 919221b1638SMasahiro Yamada NEEDBITS(3); 920221b1638SMasahiro Yamada state->lens[order[state->have++]] = (unsigned short)BITS(3); 921221b1638SMasahiro Yamada DROPBITS(3); 922221b1638SMasahiro Yamada } 923221b1638SMasahiro Yamada while (state->have < 19) 924221b1638SMasahiro Yamada state->lens[order[state->have++]] = 0; 925221b1638SMasahiro Yamada state->next = state->codes; 926221b1638SMasahiro Yamada state->lencode = (const code FAR *)(state->next); 927221b1638SMasahiro Yamada state->lenbits = 7; 928221b1638SMasahiro Yamada ret = inflate_table(CODES, state->lens, 19, &(state->next), 929221b1638SMasahiro Yamada &(state->lenbits), state->work); 930221b1638SMasahiro Yamada if (ret) { 931221b1638SMasahiro Yamada strm->msg = (char *)"invalid code lengths set"; 932221b1638SMasahiro Yamada state->mode = BAD; 933221b1638SMasahiro Yamada break; 934221b1638SMasahiro Yamada } 935221b1638SMasahiro Yamada Tracev((stderr, "inflate: code lengths ok\n")); 936221b1638SMasahiro Yamada state->have = 0; 937221b1638SMasahiro Yamada state->mode = CODELENS; 938a194255dSDaniel Boulby /* fallthrough */ 939221b1638SMasahiro Yamada case CODELENS: 940221b1638SMasahiro Yamada while (state->have < state->nlen + state->ndist) { 941221b1638SMasahiro Yamada for (;;) { 942221b1638SMasahiro Yamada here = state->lencode[BITS(state->lenbits)]; 943221b1638SMasahiro Yamada if ((unsigned)(here.bits) <= bits) break; 944221b1638SMasahiro Yamada PULLBYTE(); 945221b1638SMasahiro Yamada } 946221b1638SMasahiro Yamada if (here.val < 16) { 947221b1638SMasahiro Yamada DROPBITS(here.bits); 948221b1638SMasahiro Yamada state->lens[state->have++] = here.val; 949221b1638SMasahiro Yamada } 950221b1638SMasahiro Yamada else { 951221b1638SMasahiro Yamada if (here.val == 16) { 952221b1638SMasahiro Yamada NEEDBITS(here.bits + 2); 953221b1638SMasahiro Yamada DROPBITS(here.bits); 954221b1638SMasahiro Yamada if (state->have == 0) { 955221b1638SMasahiro Yamada strm->msg = (char *)"invalid bit length repeat"; 956221b1638SMasahiro Yamada state->mode = BAD; 957221b1638SMasahiro Yamada break; 958221b1638SMasahiro Yamada } 959221b1638SMasahiro Yamada len = state->lens[state->have - 1]; 960221b1638SMasahiro Yamada copy = 3 + BITS(2); 961221b1638SMasahiro Yamada DROPBITS(2); 962221b1638SMasahiro Yamada } 963221b1638SMasahiro Yamada else if (here.val == 17) { 964221b1638SMasahiro Yamada NEEDBITS(here.bits + 3); 965221b1638SMasahiro Yamada DROPBITS(here.bits); 966221b1638SMasahiro Yamada len = 0; 967221b1638SMasahiro Yamada copy = 3 + BITS(3); 968221b1638SMasahiro Yamada DROPBITS(3); 969221b1638SMasahiro Yamada } 970221b1638SMasahiro Yamada else { 971221b1638SMasahiro Yamada NEEDBITS(here.bits + 7); 972221b1638SMasahiro Yamada DROPBITS(here.bits); 973221b1638SMasahiro Yamada len = 0; 974221b1638SMasahiro Yamada copy = 11 + BITS(7); 975221b1638SMasahiro Yamada DROPBITS(7); 976221b1638SMasahiro Yamada } 977221b1638SMasahiro Yamada if (state->have + copy > state->nlen + state->ndist) { 978221b1638SMasahiro Yamada strm->msg = (char *)"invalid bit length repeat"; 979221b1638SMasahiro Yamada state->mode = BAD; 980221b1638SMasahiro Yamada break; 981221b1638SMasahiro Yamada } 982221b1638SMasahiro Yamada while (copy--) 983221b1638SMasahiro Yamada state->lens[state->have++] = (unsigned short)len; 984221b1638SMasahiro Yamada } 985221b1638SMasahiro Yamada } 986221b1638SMasahiro Yamada 987221b1638SMasahiro Yamada /* handle error breaks in while */ 988221b1638SMasahiro Yamada if (state->mode == BAD) break; 989221b1638SMasahiro Yamada 990221b1638SMasahiro Yamada /* check for end-of-block code (better have one) */ 991221b1638SMasahiro Yamada if (state->lens[256] == 0) { 992221b1638SMasahiro Yamada strm->msg = (char *)"invalid code -- missing end-of-block"; 993221b1638SMasahiro Yamada state->mode = BAD; 994221b1638SMasahiro Yamada break; 995221b1638SMasahiro Yamada } 996221b1638SMasahiro Yamada 997221b1638SMasahiro Yamada /* build code tables -- note: do not change the lenbits or distbits 998221b1638SMasahiro Yamada values here (9 and 6) without reading the comments in inftrees.h 999221b1638SMasahiro Yamada concerning the ENOUGH constants, which depend on those values */ 1000221b1638SMasahiro Yamada state->next = state->codes; 1001221b1638SMasahiro Yamada state->lencode = (const code FAR *)(state->next); 1002221b1638SMasahiro Yamada state->lenbits = 9; 1003221b1638SMasahiro Yamada ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), 1004221b1638SMasahiro Yamada &(state->lenbits), state->work); 1005221b1638SMasahiro Yamada if (ret) { 1006221b1638SMasahiro Yamada strm->msg = (char *)"invalid literal/lengths set"; 1007221b1638SMasahiro Yamada state->mode = BAD; 1008221b1638SMasahiro Yamada break; 1009221b1638SMasahiro Yamada } 1010221b1638SMasahiro Yamada state->distcode = (const code FAR *)(state->next); 1011221b1638SMasahiro Yamada state->distbits = 6; 1012221b1638SMasahiro Yamada ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, 1013221b1638SMasahiro Yamada &(state->next), &(state->distbits), state->work); 1014221b1638SMasahiro Yamada if (ret) { 1015221b1638SMasahiro Yamada strm->msg = (char *)"invalid distances set"; 1016221b1638SMasahiro Yamada state->mode = BAD; 1017221b1638SMasahiro Yamada break; 1018221b1638SMasahiro Yamada } 1019221b1638SMasahiro Yamada Tracev((stderr, "inflate: codes ok\n")); 1020221b1638SMasahiro Yamada state->mode = LEN_; 1021221b1638SMasahiro Yamada if (flush == Z_TREES) goto inf_leave; 1022a194255dSDaniel Boulby /* fallthrough */ 1023221b1638SMasahiro Yamada case LEN_: 1024221b1638SMasahiro Yamada state->mode = LEN; 1025a194255dSDaniel Boulby /* fallthrough */ 1026221b1638SMasahiro Yamada case LEN: 1027221b1638SMasahiro Yamada if (have >= 6 && left >= 258) { 1028221b1638SMasahiro Yamada RESTORE(); 1029221b1638SMasahiro Yamada inflate_fast(strm, out); 1030221b1638SMasahiro Yamada LOAD(); 1031221b1638SMasahiro Yamada if (state->mode == TYPE) 1032221b1638SMasahiro Yamada state->back = -1; 1033221b1638SMasahiro Yamada break; 1034221b1638SMasahiro Yamada } 1035221b1638SMasahiro Yamada state->back = 0; 1036221b1638SMasahiro Yamada for (;;) { 1037221b1638SMasahiro Yamada here = state->lencode[BITS(state->lenbits)]; 1038221b1638SMasahiro Yamada if ((unsigned)(here.bits) <= bits) break; 1039221b1638SMasahiro Yamada PULLBYTE(); 1040221b1638SMasahiro Yamada } 1041221b1638SMasahiro Yamada if (here.op && (here.op & 0xf0) == 0) { 1042221b1638SMasahiro Yamada last = here; 1043221b1638SMasahiro Yamada for (;;) { 1044221b1638SMasahiro Yamada here = state->lencode[last.val + 1045221b1638SMasahiro Yamada (BITS(last.bits + last.op) >> last.bits)]; 1046221b1638SMasahiro Yamada if ((unsigned)(last.bits + here.bits) <= bits) break; 1047221b1638SMasahiro Yamada PULLBYTE(); 1048221b1638SMasahiro Yamada } 1049221b1638SMasahiro Yamada DROPBITS(last.bits); 1050221b1638SMasahiro Yamada state->back += last.bits; 1051221b1638SMasahiro Yamada } 1052221b1638SMasahiro Yamada DROPBITS(here.bits); 1053221b1638SMasahiro Yamada state->back += here.bits; 1054221b1638SMasahiro Yamada state->length = (unsigned)here.val; 1055221b1638SMasahiro Yamada if ((int)(here.op) == 0) { 1056221b1638SMasahiro Yamada Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 1057221b1638SMasahiro Yamada "inflate: literal '%c'\n" : 1058221b1638SMasahiro Yamada "inflate: literal 0x%02x\n", here.val)); 1059221b1638SMasahiro Yamada state->mode = LIT; 1060221b1638SMasahiro Yamada break; 1061221b1638SMasahiro Yamada } 1062221b1638SMasahiro Yamada if (here.op & 32) { 1063221b1638SMasahiro Yamada Tracevv((stderr, "inflate: end of block\n")); 1064221b1638SMasahiro Yamada state->back = -1; 1065221b1638SMasahiro Yamada state->mode = TYPE; 1066221b1638SMasahiro Yamada break; 1067221b1638SMasahiro Yamada } 1068221b1638SMasahiro Yamada if (here.op & 64) { 1069221b1638SMasahiro Yamada strm->msg = (char *)"invalid literal/length code"; 1070221b1638SMasahiro Yamada state->mode = BAD; 1071221b1638SMasahiro Yamada break; 1072221b1638SMasahiro Yamada } 1073221b1638SMasahiro Yamada state->extra = (unsigned)(here.op) & 15; 1074221b1638SMasahiro Yamada state->mode = LENEXT; 1075a194255dSDaniel Boulby /* fallthrough */ 1076221b1638SMasahiro Yamada case LENEXT: 1077221b1638SMasahiro Yamada if (state->extra) { 1078221b1638SMasahiro Yamada NEEDBITS(state->extra); 1079221b1638SMasahiro Yamada state->length += BITS(state->extra); 1080221b1638SMasahiro Yamada DROPBITS(state->extra); 1081221b1638SMasahiro Yamada state->back += state->extra; 1082221b1638SMasahiro Yamada } 1083221b1638SMasahiro Yamada Tracevv((stderr, "inflate: length %u\n", state->length)); 1084221b1638SMasahiro Yamada state->was = state->length; 1085221b1638SMasahiro Yamada state->mode = DIST; 1086a194255dSDaniel Boulby /* fallthrough */ 1087221b1638SMasahiro Yamada case DIST: 1088221b1638SMasahiro Yamada for (;;) { 1089221b1638SMasahiro Yamada here = state->distcode[BITS(state->distbits)]; 1090221b1638SMasahiro Yamada if ((unsigned)(here.bits) <= bits) break; 1091221b1638SMasahiro Yamada PULLBYTE(); 1092221b1638SMasahiro Yamada } 1093221b1638SMasahiro Yamada if ((here.op & 0xf0) == 0) { 1094221b1638SMasahiro Yamada last = here; 1095221b1638SMasahiro Yamada for (;;) { 1096221b1638SMasahiro Yamada here = state->distcode[last.val + 1097221b1638SMasahiro Yamada (BITS(last.bits + last.op) >> last.bits)]; 1098221b1638SMasahiro Yamada if ((unsigned)(last.bits + here.bits) <= bits) break; 1099221b1638SMasahiro Yamada PULLBYTE(); 1100221b1638SMasahiro Yamada } 1101221b1638SMasahiro Yamada DROPBITS(last.bits); 1102221b1638SMasahiro Yamada state->back += last.bits; 1103221b1638SMasahiro Yamada } 1104221b1638SMasahiro Yamada DROPBITS(here.bits); 1105221b1638SMasahiro Yamada state->back += here.bits; 1106221b1638SMasahiro Yamada if (here.op & 64) { 1107221b1638SMasahiro Yamada strm->msg = (char *)"invalid distance code"; 1108221b1638SMasahiro Yamada state->mode = BAD; 1109221b1638SMasahiro Yamada break; 1110221b1638SMasahiro Yamada } 1111221b1638SMasahiro Yamada state->offset = (unsigned)here.val; 1112221b1638SMasahiro Yamada state->extra = (unsigned)(here.op) & 15; 1113221b1638SMasahiro Yamada state->mode = DISTEXT; 1114a194255dSDaniel Boulby /* fallthrough */ 1115221b1638SMasahiro Yamada case DISTEXT: 1116221b1638SMasahiro Yamada if (state->extra) { 1117221b1638SMasahiro Yamada NEEDBITS(state->extra); 1118221b1638SMasahiro Yamada state->offset += BITS(state->extra); 1119221b1638SMasahiro Yamada DROPBITS(state->extra); 1120221b1638SMasahiro Yamada state->back += state->extra; 1121221b1638SMasahiro Yamada } 1122221b1638SMasahiro Yamada #ifdef INFLATE_STRICT 1123221b1638SMasahiro Yamada if (state->offset > state->dmax) { 1124221b1638SMasahiro Yamada strm->msg = (char *)"invalid distance too far back"; 1125221b1638SMasahiro Yamada state->mode = BAD; 1126221b1638SMasahiro Yamada break; 1127221b1638SMasahiro Yamada } 1128221b1638SMasahiro Yamada #endif 1129221b1638SMasahiro Yamada Tracevv((stderr, "inflate: distance %u\n", state->offset)); 1130221b1638SMasahiro Yamada state->mode = MATCH; 1131a194255dSDaniel Boulby /* fallthrough */ 1132221b1638SMasahiro Yamada case MATCH: 1133221b1638SMasahiro Yamada if (left == 0) goto inf_leave; 1134221b1638SMasahiro Yamada copy = out - left; 1135221b1638SMasahiro Yamada if (state->offset > copy) { /* copy from window */ 1136221b1638SMasahiro Yamada copy = state->offset - copy; 1137221b1638SMasahiro Yamada if (copy > state->whave) { 1138221b1638SMasahiro Yamada if (state->sane) { 1139221b1638SMasahiro Yamada strm->msg = (char *)"invalid distance too far back"; 1140221b1638SMasahiro Yamada state->mode = BAD; 1141221b1638SMasahiro Yamada break; 1142221b1638SMasahiro Yamada } 1143221b1638SMasahiro Yamada #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 1144221b1638SMasahiro Yamada Trace((stderr, "inflate.c too far\n")); 1145221b1638SMasahiro Yamada copy -= state->whave; 1146221b1638SMasahiro Yamada if (copy > state->length) copy = state->length; 1147221b1638SMasahiro Yamada if (copy > left) copy = left; 1148221b1638SMasahiro Yamada left -= copy; 1149221b1638SMasahiro Yamada state->length -= copy; 1150221b1638SMasahiro Yamada do { 1151221b1638SMasahiro Yamada *put++ = 0; 1152221b1638SMasahiro Yamada } while (--copy); 1153221b1638SMasahiro Yamada if (state->length == 0) state->mode = LEN; 1154221b1638SMasahiro Yamada break; 1155221b1638SMasahiro Yamada #endif 1156221b1638SMasahiro Yamada } 1157221b1638SMasahiro Yamada if (copy > state->wnext) { 1158221b1638SMasahiro Yamada copy -= state->wnext; 1159221b1638SMasahiro Yamada from = state->window + (state->wsize - copy); 1160221b1638SMasahiro Yamada } 1161221b1638SMasahiro Yamada else 1162221b1638SMasahiro Yamada from = state->window + (state->wnext - copy); 1163221b1638SMasahiro Yamada if (copy > state->length) copy = state->length; 1164221b1638SMasahiro Yamada } 1165221b1638SMasahiro Yamada else { /* copy from output */ 1166221b1638SMasahiro Yamada from = put - state->offset; 1167221b1638SMasahiro Yamada copy = state->length; 1168221b1638SMasahiro Yamada } 1169221b1638SMasahiro Yamada if (copy > left) copy = left; 1170221b1638SMasahiro Yamada left -= copy; 1171221b1638SMasahiro Yamada state->length -= copy; 1172221b1638SMasahiro Yamada do { 1173221b1638SMasahiro Yamada *put++ = *from++; 1174221b1638SMasahiro Yamada } while (--copy); 1175221b1638SMasahiro Yamada if (state->length == 0) state->mode = LEN; 1176221b1638SMasahiro Yamada break; 1177221b1638SMasahiro Yamada case LIT: 1178221b1638SMasahiro Yamada if (left == 0) goto inf_leave; 1179221b1638SMasahiro Yamada *put++ = (unsigned char)(state->length); 1180221b1638SMasahiro Yamada left--; 1181221b1638SMasahiro Yamada state->mode = LEN; 1182221b1638SMasahiro Yamada break; 1183221b1638SMasahiro Yamada case CHECK: 1184221b1638SMasahiro Yamada if (state->wrap) { 1185221b1638SMasahiro Yamada NEEDBITS(32); 1186221b1638SMasahiro Yamada out -= left; 1187221b1638SMasahiro Yamada strm->total_out += out; 1188221b1638SMasahiro Yamada state->total += out; 1189221b1638SMasahiro Yamada if ((state->wrap & 4) && out) 1190221b1638SMasahiro Yamada strm->adler = state->check = 1191a194255dSDaniel Boulby UPDATE_CHECK(state->check, put - out, out); 1192221b1638SMasahiro Yamada out = left; 1193221b1638SMasahiro Yamada if ((state->wrap & 4) && ( 1194221b1638SMasahiro Yamada #ifdef GUNZIP 1195221b1638SMasahiro Yamada state->flags ? hold : 1196221b1638SMasahiro Yamada #endif 1197221b1638SMasahiro Yamada ZSWAP32(hold)) != state->check) { 1198221b1638SMasahiro Yamada strm->msg = (char *)"incorrect data check"; 1199221b1638SMasahiro Yamada state->mode = BAD; 1200221b1638SMasahiro Yamada break; 1201221b1638SMasahiro Yamada } 1202221b1638SMasahiro Yamada INITBITS(); 1203221b1638SMasahiro Yamada Tracev((stderr, "inflate: check matches trailer\n")); 1204221b1638SMasahiro Yamada } 1205221b1638SMasahiro Yamada #ifdef GUNZIP 1206221b1638SMasahiro Yamada state->mode = LENGTH; 1207a194255dSDaniel Boulby /* fallthrough */ 1208221b1638SMasahiro Yamada case LENGTH: 1209221b1638SMasahiro Yamada if (state->wrap && state->flags) { 1210221b1638SMasahiro Yamada NEEDBITS(32); 1211a194255dSDaniel Boulby if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { 1212221b1638SMasahiro Yamada strm->msg = (char *)"incorrect length check"; 1213221b1638SMasahiro Yamada state->mode = BAD; 1214221b1638SMasahiro Yamada break; 1215221b1638SMasahiro Yamada } 1216221b1638SMasahiro Yamada INITBITS(); 1217221b1638SMasahiro Yamada Tracev((stderr, "inflate: length matches trailer\n")); 1218221b1638SMasahiro Yamada } 1219221b1638SMasahiro Yamada #endif 1220221b1638SMasahiro Yamada state->mode = DONE; 1221a194255dSDaniel Boulby /* fallthrough */ 1222221b1638SMasahiro Yamada case DONE: 1223221b1638SMasahiro Yamada ret = Z_STREAM_END; 1224221b1638SMasahiro Yamada goto inf_leave; 1225221b1638SMasahiro Yamada case BAD: 1226221b1638SMasahiro Yamada ret = Z_DATA_ERROR; 1227221b1638SMasahiro Yamada goto inf_leave; 1228221b1638SMasahiro Yamada case MEM: 1229221b1638SMasahiro Yamada return Z_MEM_ERROR; 1230221b1638SMasahiro Yamada case SYNC: 1231a194255dSDaniel Boulby /* fallthrough */ 1232221b1638SMasahiro Yamada default: 1233221b1638SMasahiro Yamada return Z_STREAM_ERROR; 1234221b1638SMasahiro Yamada } 1235221b1638SMasahiro Yamada 1236221b1638SMasahiro Yamada /* 1237221b1638SMasahiro Yamada Return from inflate(), updating the total counts and the check value. 1238221b1638SMasahiro Yamada If there was no progress during the inflate() call, return a buffer 1239221b1638SMasahiro Yamada error. Call updatewindow() to create and/or update the window state. 1240221b1638SMasahiro Yamada Note: a memory error from inflate() is non-recoverable. 1241221b1638SMasahiro Yamada */ 1242221b1638SMasahiro Yamada inf_leave: 1243221b1638SMasahiro Yamada RESTORE(); 1244221b1638SMasahiro Yamada if (state->wsize || (out != strm->avail_out && state->mode < BAD && 1245221b1638SMasahiro Yamada (state->mode < CHECK || flush != Z_FINISH))) 1246221b1638SMasahiro Yamada if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { 1247221b1638SMasahiro Yamada state->mode = MEM; 1248221b1638SMasahiro Yamada return Z_MEM_ERROR; 1249221b1638SMasahiro Yamada } 1250221b1638SMasahiro Yamada in -= strm->avail_in; 1251221b1638SMasahiro Yamada out -= strm->avail_out; 1252221b1638SMasahiro Yamada strm->total_in += in; 1253221b1638SMasahiro Yamada strm->total_out += out; 1254221b1638SMasahiro Yamada state->total += out; 1255221b1638SMasahiro Yamada if ((state->wrap & 4) && out) 1256221b1638SMasahiro Yamada strm->adler = state->check = 1257a194255dSDaniel Boulby UPDATE_CHECK(state->check, strm->next_out - out, out); 1258221b1638SMasahiro Yamada strm->data_type = (int)state->bits + (state->last ? 64 : 0) + 1259221b1638SMasahiro Yamada (state->mode == TYPE ? 128 : 0) + 1260221b1638SMasahiro Yamada (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); 1261221b1638SMasahiro Yamada if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) 1262221b1638SMasahiro Yamada ret = Z_BUF_ERROR; 1263221b1638SMasahiro Yamada return ret; 1264221b1638SMasahiro Yamada } 1265221b1638SMasahiro Yamada 1266*fd39217aSManish Pandey int ZEXPORT inflateEnd(z_streamp strm) { 1267221b1638SMasahiro Yamada struct inflate_state FAR *state; 1268221b1638SMasahiro Yamada if (inflateStateCheck(strm)) 1269221b1638SMasahiro Yamada return Z_STREAM_ERROR; 1270221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1271221b1638SMasahiro Yamada if (state->window != Z_NULL) ZFREE(strm, state->window); 1272221b1638SMasahiro Yamada ZFREE(strm, strm->state); 1273221b1638SMasahiro Yamada strm->state = Z_NULL; 1274221b1638SMasahiro Yamada Tracev((stderr, "inflate: end\n")); 1275221b1638SMasahiro Yamada return Z_OK; 1276221b1638SMasahiro Yamada } 1277221b1638SMasahiro Yamada 1278*fd39217aSManish Pandey int ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, 1279*fd39217aSManish Pandey uInt *dictLength) { 1280221b1638SMasahiro Yamada struct inflate_state FAR *state; 1281221b1638SMasahiro Yamada 1282221b1638SMasahiro Yamada /* check state */ 1283221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1284221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1285221b1638SMasahiro Yamada 1286221b1638SMasahiro Yamada /* copy dictionary */ 1287221b1638SMasahiro Yamada if (state->whave && dictionary != Z_NULL) { 1288221b1638SMasahiro Yamada zmemcpy(dictionary, state->window + state->wnext, 1289221b1638SMasahiro Yamada state->whave - state->wnext); 1290221b1638SMasahiro Yamada zmemcpy(dictionary + state->whave - state->wnext, 1291221b1638SMasahiro Yamada state->window, state->wnext); 1292221b1638SMasahiro Yamada } 1293221b1638SMasahiro Yamada if (dictLength != Z_NULL) 1294221b1638SMasahiro Yamada *dictLength = state->whave; 1295221b1638SMasahiro Yamada return Z_OK; 1296221b1638SMasahiro Yamada } 1297221b1638SMasahiro Yamada 1298*fd39217aSManish Pandey int ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, 1299*fd39217aSManish Pandey uInt dictLength) { 1300221b1638SMasahiro Yamada struct inflate_state FAR *state; 1301221b1638SMasahiro Yamada unsigned long dictid; 1302221b1638SMasahiro Yamada int ret; 1303221b1638SMasahiro Yamada 1304221b1638SMasahiro Yamada /* check state */ 1305221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1306221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1307221b1638SMasahiro Yamada if (state->wrap != 0 && state->mode != DICT) 1308221b1638SMasahiro Yamada return Z_STREAM_ERROR; 1309221b1638SMasahiro Yamada 1310221b1638SMasahiro Yamada /* check for correct dictionary identifier */ 1311221b1638SMasahiro Yamada if (state->mode == DICT) { 1312221b1638SMasahiro Yamada dictid = adler32(0L, Z_NULL, 0); 1313221b1638SMasahiro Yamada dictid = adler32(dictid, dictionary, dictLength); 1314221b1638SMasahiro Yamada if (dictid != state->check) 1315221b1638SMasahiro Yamada return Z_DATA_ERROR; 1316221b1638SMasahiro Yamada } 1317221b1638SMasahiro Yamada 1318221b1638SMasahiro Yamada /* copy dictionary to window using updatewindow(), which will amend the 1319221b1638SMasahiro Yamada existing dictionary if appropriate */ 1320221b1638SMasahiro Yamada ret = updatewindow(strm, dictionary + dictLength, dictLength); 1321221b1638SMasahiro Yamada if (ret) { 1322221b1638SMasahiro Yamada state->mode = MEM; 1323221b1638SMasahiro Yamada return Z_MEM_ERROR; 1324221b1638SMasahiro Yamada } 1325221b1638SMasahiro Yamada state->havedict = 1; 1326221b1638SMasahiro Yamada Tracev((stderr, "inflate: dictionary set\n")); 1327221b1638SMasahiro Yamada return Z_OK; 1328221b1638SMasahiro Yamada } 1329221b1638SMasahiro Yamada 1330*fd39217aSManish Pandey int ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) { 1331221b1638SMasahiro Yamada struct inflate_state FAR *state; 1332221b1638SMasahiro Yamada 1333221b1638SMasahiro Yamada /* check state */ 1334221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1335221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1336221b1638SMasahiro Yamada if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; 1337221b1638SMasahiro Yamada 1338221b1638SMasahiro Yamada /* save header structure */ 1339221b1638SMasahiro Yamada state->head = head; 1340221b1638SMasahiro Yamada head->done = 0; 1341221b1638SMasahiro Yamada return Z_OK; 1342221b1638SMasahiro Yamada } 1343221b1638SMasahiro Yamada 1344221b1638SMasahiro Yamada /* 1345221b1638SMasahiro Yamada Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found 1346221b1638SMasahiro Yamada or when out of input. When called, *have is the number of pattern bytes 1347221b1638SMasahiro Yamada found in order so far, in 0..3. On return *have is updated to the new 1348221b1638SMasahiro Yamada state. If on return *have equals four, then the pattern was found and the 1349221b1638SMasahiro Yamada return value is how many bytes were read including the last byte of the 1350221b1638SMasahiro Yamada pattern. If *have is less than four, then the pattern has not been found 1351221b1638SMasahiro Yamada yet and the return value is len. In the latter case, syncsearch() can be 1352221b1638SMasahiro Yamada called again with more data and the *have state. *have is initialized to 1353221b1638SMasahiro Yamada zero for the first call. 1354221b1638SMasahiro Yamada */ 1355*fd39217aSManish Pandey local unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, 1356*fd39217aSManish Pandey unsigned len) { 1357221b1638SMasahiro Yamada unsigned got; 1358221b1638SMasahiro Yamada unsigned next; 1359221b1638SMasahiro Yamada 1360221b1638SMasahiro Yamada got = *have; 1361221b1638SMasahiro Yamada next = 0; 1362221b1638SMasahiro Yamada while (next < len && got < 4) { 1363221b1638SMasahiro Yamada if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) 1364221b1638SMasahiro Yamada got++; 1365221b1638SMasahiro Yamada else if (buf[next]) 1366221b1638SMasahiro Yamada got = 0; 1367221b1638SMasahiro Yamada else 1368221b1638SMasahiro Yamada got = 4 - got; 1369221b1638SMasahiro Yamada next++; 1370221b1638SMasahiro Yamada } 1371221b1638SMasahiro Yamada *have = got; 1372221b1638SMasahiro Yamada return next; 1373221b1638SMasahiro Yamada } 1374221b1638SMasahiro Yamada 1375*fd39217aSManish Pandey int ZEXPORT inflateSync(z_streamp strm) { 1376221b1638SMasahiro Yamada unsigned len; /* number of bytes to look at or looked at */ 1377a194255dSDaniel Boulby int flags; /* temporary to save header status */ 1378221b1638SMasahiro Yamada unsigned long in, out; /* temporary to save total_in and total_out */ 1379221b1638SMasahiro Yamada unsigned char buf[4]; /* to restore bit buffer to byte string */ 1380221b1638SMasahiro Yamada struct inflate_state FAR *state; 1381221b1638SMasahiro Yamada 1382221b1638SMasahiro Yamada /* check parameters */ 1383221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1384221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1385221b1638SMasahiro Yamada if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; 1386221b1638SMasahiro Yamada 1387221b1638SMasahiro Yamada /* if first time, start search in bit buffer */ 1388221b1638SMasahiro Yamada if (state->mode != SYNC) { 1389221b1638SMasahiro Yamada state->mode = SYNC; 1390221b1638SMasahiro Yamada state->hold <<= state->bits & 7; 1391221b1638SMasahiro Yamada state->bits -= state->bits & 7; 1392221b1638SMasahiro Yamada len = 0; 1393221b1638SMasahiro Yamada while (state->bits >= 8) { 1394221b1638SMasahiro Yamada buf[len++] = (unsigned char)(state->hold); 1395221b1638SMasahiro Yamada state->hold >>= 8; 1396221b1638SMasahiro Yamada state->bits -= 8; 1397221b1638SMasahiro Yamada } 1398221b1638SMasahiro Yamada state->have = 0; 1399221b1638SMasahiro Yamada syncsearch(&(state->have), buf, len); 1400221b1638SMasahiro Yamada } 1401221b1638SMasahiro Yamada 1402221b1638SMasahiro Yamada /* search available input */ 1403221b1638SMasahiro Yamada len = syncsearch(&(state->have), strm->next_in, strm->avail_in); 1404221b1638SMasahiro Yamada strm->avail_in -= len; 1405221b1638SMasahiro Yamada strm->next_in += len; 1406221b1638SMasahiro Yamada strm->total_in += len; 1407221b1638SMasahiro Yamada 1408221b1638SMasahiro Yamada /* return no joy or set up to restart inflate() on a new block */ 1409221b1638SMasahiro Yamada if (state->have != 4) return Z_DATA_ERROR; 1410a194255dSDaniel Boulby if (state->flags == -1) 1411a194255dSDaniel Boulby state->wrap = 0; /* if no header yet, treat as raw */ 1412a194255dSDaniel Boulby else 1413a194255dSDaniel Boulby state->wrap &= ~4; /* no point in computing a check value now */ 1414a194255dSDaniel Boulby flags = state->flags; 1415221b1638SMasahiro Yamada in = strm->total_in; out = strm->total_out; 1416221b1638SMasahiro Yamada inflateReset(strm); 1417221b1638SMasahiro Yamada strm->total_in = in; strm->total_out = out; 1418a194255dSDaniel Boulby state->flags = flags; 1419221b1638SMasahiro Yamada state->mode = TYPE; 1420221b1638SMasahiro Yamada return Z_OK; 1421221b1638SMasahiro Yamada } 1422221b1638SMasahiro Yamada 1423221b1638SMasahiro Yamada /* 1424221b1638SMasahiro Yamada Returns true if inflate is currently at the end of a block generated by 1425221b1638SMasahiro Yamada Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP 1426221b1638SMasahiro Yamada implementation to provide an additional safety check. PPP uses 1427221b1638SMasahiro Yamada Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored 1428221b1638SMasahiro Yamada block. When decompressing, PPP checks that at the end of input packet, 1429221b1638SMasahiro Yamada inflate is waiting for these length bytes. 1430221b1638SMasahiro Yamada */ 1431*fd39217aSManish Pandey int ZEXPORT inflateSyncPoint(z_streamp strm) { 1432221b1638SMasahiro Yamada struct inflate_state FAR *state; 1433221b1638SMasahiro Yamada 1434221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1435221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1436221b1638SMasahiro Yamada return state->mode == STORED && state->bits == 0; 1437221b1638SMasahiro Yamada } 1438221b1638SMasahiro Yamada 1439*fd39217aSManish Pandey int ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { 1440221b1638SMasahiro Yamada struct inflate_state FAR *state; 1441221b1638SMasahiro Yamada struct inflate_state FAR *copy; 1442221b1638SMasahiro Yamada unsigned char FAR *window; 1443221b1638SMasahiro Yamada unsigned wsize; 1444221b1638SMasahiro Yamada 1445221b1638SMasahiro Yamada /* check input */ 1446221b1638SMasahiro Yamada if (inflateStateCheck(source) || dest == Z_NULL) 1447221b1638SMasahiro Yamada return Z_STREAM_ERROR; 1448221b1638SMasahiro Yamada state = (struct inflate_state FAR *)source->state; 1449221b1638SMasahiro Yamada 1450221b1638SMasahiro Yamada /* allocate space */ 1451221b1638SMasahiro Yamada copy = (struct inflate_state FAR *) 1452221b1638SMasahiro Yamada ZALLOC(source, 1, sizeof(struct inflate_state)); 1453221b1638SMasahiro Yamada if (copy == Z_NULL) return Z_MEM_ERROR; 1454221b1638SMasahiro Yamada window = Z_NULL; 1455221b1638SMasahiro Yamada if (state->window != Z_NULL) { 1456221b1638SMasahiro Yamada window = (unsigned char FAR *) 1457221b1638SMasahiro Yamada ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); 1458221b1638SMasahiro Yamada if (window == Z_NULL) { 1459221b1638SMasahiro Yamada ZFREE(source, copy); 1460221b1638SMasahiro Yamada return Z_MEM_ERROR; 1461221b1638SMasahiro Yamada } 1462221b1638SMasahiro Yamada } 1463221b1638SMasahiro Yamada 1464221b1638SMasahiro Yamada /* copy state */ 1465221b1638SMasahiro Yamada zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); 1466221b1638SMasahiro Yamada zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); 1467221b1638SMasahiro Yamada copy->strm = dest; 1468221b1638SMasahiro Yamada if (state->lencode >= state->codes && 1469221b1638SMasahiro Yamada state->lencode <= state->codes + ENOUGH - 1) { 1470221b1638SMasahiro Yamada copy->lencode = copy->codes + (state->lencode - state->codes); 1471221b1638SMasahiro Yamada copy->distcode = copy->codes + (state->distcode - state->codes); 1472221b1638SMasahiro Yamada } 1473221b1638SMasahiro Yamada copy->next = copy->codes + (state->next - state->codes); 1474221b1638SMasahiro Yamada if (window != Z_NULL) { 1475221b1638SMasahiro Yamada wsize = 1U << state->wbits; 1476221b1638SMasahiro Yamada zmemcpy(window, state->window, wsize); 1477221b1638SMasahiro Yamada } 1478221b1638SMasahiro Yamada copy->window = window; 1479221b1638SMasahiro Yamada dest->state = (struct internal_state FAR *)copy; 1480221b1638SMasahiro Yamada return Z_OK; 1481221b1638SMasahiro Yamada } 1482221b1638SMasahiro Yamada 1483*fd39217aSManish Pandey int ZEXPORT inflateUndermine(z_streamp strm, int subvert) { 1484221b1638SMasahiro Yamada struct inflate_state FAR *state; 1485221b1638SMasahiro Yamada 1486221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1487221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1488221b1638SMasahiro Yamada #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 1489221b1638SMasahiro Yamada state->sane = !subvert; 1490221b1638SMasahiro Yamada return Z_OK; 1491221b1638SMasahiro Yamada #else 1492221b1638SMasahiro Yamada (void)subvert; 1493221b1638SMasahiro Yamada state->sane = 1; 1494221b1638SMasahiro Yamada return Z_DATA_ERROR; 1495221b1638SMasahiro Yamada #endif 1496221b1638SMasahiro Yamada } 1497221b1638SMasahiro Yamada 1498*fd39217aSManish Pandey int ZEXPORT inflateValidate(z_streamp strm, int check) { 1499221b1638SMasahiro Yamada struct inflate_state FAR *state; 1500221b1638SMasahiro Yamada 1501221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1502221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1503a194255dSDaniel Boulby if (check && state->wrap) 1504221b1638SMasahiro Yamada state->wrap |= 4; 1505221b1638SMasahiro Yamada else 1506221b1638SMasahiro Yamada state->wrap &= ~4; 1507221b1638SMasahiro Yamada return Z_OK; 1508221b1638SMasahiro Yamada } 1509221b1638SMasahiro Yamada 1510*fd39217aSManish Pandey long ZEXPORT inflateMark(z_streamp strm) { 1511221b1638SMasahiro Yamada struct inflate_state FAR *state; 1512221b1638SMasahiro Yamada 1513221b1638SMasahiro Yamada if (inflateStateCheck(strm)) 1514221b1638SMasahiro Yamada return -(1L << 16); 1515221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1516221b1638SMasahiro Yamada return (long)(((unsigned long)((long)state->back)) << 16) + 1517221b1638SMasahiro Yamada (state->mode == COPY ? state->length : 1518221b1638SMasahiro Yamada (state->mode == MATCH ? state->was - state->length : 0)); 1519221b1638SMasahiro Yamada } 1520221b1638SMasahiro Yamada 1521*fd39217aSManish Pandey unsigned long ZEXPORT inflateCodesUsed(z_streamp strm) { 1522221b1638SMasahiro Yamada struct inflate_state FAR *state; 1523221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return (unsigned long)-1; 1524221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1525221b1638SMasahiro Yamada return (unsigned long)(state->next - state->codes); 1526221b1638SMasahiro Yamada } 1527