1221b1638SMasahiro Yamada /* inflate.c -- zlib decompression 2*a194255dSDaniel 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 94221b1638SMasahiro Yamada /* function prototypes */ 95221b1638SMasahiro Yamada local int inflateStateCheck OF((z_streamp strm)); 96221b1638SMasahiro Yamada local void fixedtables OF((struct inflate_state FAR *state)); 97221b1638SMasahiro Yamada local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, 98221b1638SMasahiro Yamada unsigned copy)); 99221b1638SMasahiro Yamada #ifdef BUILDFIXED 100221b1638SMasahiro Yamada void makefixed OF((void)); 101221b1638SMasahiro Yamada #endif 102221b1638SMasahiro Yamada local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, 103221b1638SMasahiro Yamada unsigned len)); 104221b1638SMasahiro Yamada 105221b1638SMasahiro Yamada local int inflateStateCheck(strm) 106221b1638SMasahiro Yamada z_streamp strm; 107221b1638SMasahiro Yamada { 108221b1638SMasahiro Yamada struct inflate_state FAR *state; 109221b1638SMasahiro Yamada if (strm == Z_NULL || 110221b1638SMasahiro Yamada strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) 111221b1638SMasahiro Yamada return 1; 112221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 113221b1638SMasahiro Yamada if (state == Z_NULL || state->strm != strm || 114221b1638SMasahiro Yamada state->mode < HEAD || state->mode > SYNC) 115221b1638SMasahiro Yamada return 1; 116221b1638SMasahiro Yamada return 0; 117221b1638SMasahiro Yamada } 118221b1638SMasahiro Yamada 119221b1638SMasahiro Yamada int ZEXPORT inflateResetKeep(strm) 120221b1638SMasahiro Yamada z_streamp strm; 121221b1638SMasahiro Yamada { 122221b1638SMasahiro Yamada struct inflate_state FAR *state; 123221b1638SMasahiro Yamada 124221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 125221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 126221b1638SMasahiro Yamada strm->total_in = strm->total_out = state->total = 0; 127221b1638SMasahiro Yamada strm->msg = Z_NULL; 128221b1638SMasahiro Yamada if (state->wrap) /* to support ill-conceived Java test suite */ 129221b1638SMasahiro Yamada strm->adler = state->wrap & 1; 130221b1638SMasahiro Yamada state->mode = HEAD; 131221b1638SMasahiro Yamada state->last = 0; 132221b1638SMasahiro Yamada state->havedict = 0; 133*a194255dSDaniel Boulby state->flags = -1; 134221b1638SMasahiro Yamada state->dmax = 32768U; 135221b1638SMasahiro Yamada state->head = Z_NULL; 136221b1638SMasahiro Yamada state->hold = 0; 137221b1638SMasahiro Yamada state->bits = 0; 138221b1638SMasahiro Yamada state->lencode = state->distcode = state->next = state->codes; 139221b1638SMasahiro Yamada state->sane = 1; 140221b1638SMasahiro Yamada state->back = -1; 141221b1638SMasahiro Yamada Tracev((stderr, "inflate: reset\n")); 142221b1638SMasahiro Yamada return Z_OK; 143221b1638SMasahiro Yamada } 144221b1638SMasahiro Yamada 145221b1638SMasahiro Yamada int ZEXPORT inflateReset(strm) 146221b1638SMasahiro Yamada z_streamp strm; 147221b1638SMasahiro Yamada { 148221b1638SMasahiro Yamada struct inflate_state FAR *state; 149221b1638SMasahiro Yamada 150221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 151221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 152221b1638SMasahiro Yamada state->wsize = 0; 153221b1638SMasahiro Yamada state->whave = 0; 154221b1638SMasahiro Yamada state->wnext = 0; 155221b1638SMasahiro Yamada return inflateResetKeep(strm); 156221b1638SMasahiro Yamada } 157221b1638SMasahiro Yamada 158221b1638SMasahiro Yamada int ZEXPORT inflateReset2(strm, windowBits) 159221b1638SMasahiro Yamada z_streamp strm; 160221b1638SMasahiro Yamada int windowBits; 161221b1638SMasahiro Yamada { 162221b1638SMasahiro Yamada int wrap; 163221b1638SMasahiro Yamada struct inflate_state FAR *state; 164221b1638SMasahiro Yamada 165221b1638SMasahiro Yamada /* get the state */ 166221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 167221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 168221b1638SMasahiro Yamada 169221b1638SMasahiro Yamada /* extract wrap request from windowBits parameter */ 170221b1638SMasahiro Yamada if (windowBits < 0) { 171*a194255dSDaniel Boulby if (windowBits < -15) 172*a194255dSDaniel Boulby return Z_STREAM_ERROR; 173221b1638SMasahiro Yamada wrap = 0; 174221b1638SMasahiro Yamada windowBits = -windowBits; 175221b1638SMasahiro Yamada } 176221b1638SMasahiro Yamada else { 177221b1638SMasahiro Yamada wrap = (windowBits >> 4) + 5; 178221b1638SMasahiro Yamada #ifdef GUNZIP 179221b1638SMasahiro Yamada if (windowBits < 48) 180221b1638SMasahiro Yamada windowBits &= 15; 181221b1638SMasahiro Yamada #endif 182221b1638SMasahiro Yamada } 183221b1638SMasahiro Yamada 184221b1638SMasahiro Yamada /* set number of window bits, free window if different */ 185221b1638SMasahiro Yamada if (windowBits && (windowBits < 8 || windowBits > 15)) 186221b1638SMasahiro Yamada return Z_STREAM_ERROR; 187221b1638SMasahiro Yamada if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { 188221b1638SMasahiro Yamada ZFREE(strm, state->window); 189221b1638SMasahiro Yamada state->window = Z_NULL; 190221b1638SMasahiro Yamada } 191221b1638SMasahiro Yamada 192221b1638SMasahiro Yamada /* update state and reset the rest of it */ 193221b1638SMasahiro Yamada state->wrap = wrap; 194221b1638SMasahiro Yamada state->wbits = (unsigned)windowBits; 195221b1638SMasahiro Yamada return inflateReset(strm); 196221b1638SMasahiro Yamada } 197221b1638SMasahiro Yamada 198221b1638SMasahiro Yamada int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) 199221b1638SMasahiro Yamada z_streamp strm; 200221b1638SMasahiro Yamada int windowBits; 201221b1638SMasahiro Yamada const char *version; 202221b1638SMasahiro Yamada int stream_size; 203221b1638SMasahiro Yamada { 204221b1638SMasahiro Yamada int ret; 205221b1638SMasahiro Yamada struct inflate_state FAR *state; 206221b1638SMasahiro Yamada 207221b1638SMasahiro Yamada if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 208221b1638SMasahiro Yamada stream_size != (int)(sizeof(z_stream))) 209221b1638SMasahiro Yamada return Z_VERSION_ERROR; 210221b1638SMasahiro Yamada if (strm == Z_NULL) return Z_STREAM_ERROR; 211221b1638SMasahiro Yamada strm->msg = Z_NULL; /* in case we return an error */ 212221b1638SMasahiro Yamada if (strm->zalloc == (alloc_func)0) { 213221b1638SMasahiro Yamada #ifdef Z_SOLO 214221b1638SMasahiro Yamada return Z_STREAM_ERROR; 215221b1638SMasahiro Yamada #else 216221b1638SMasahiro Yamada strm->zalloc = zcalloc; 217221b1638SMasahiro Yamada strm->opaque = (voidpf)0; 218221b1638SMasahiro Yamada #endif 219221b1638SMasahiro Yamada } 220221b1638SMasahiro Yamada if (strm->zfree == (free_func)0) 221221b1638SMasahiro Yamada #ifdef Z_SOLO 222221b1638SMasahiro Yamada return Z_STREAM_ERROR; 223221b1638SMasahiro Yamada #else 224221b1638SMasahiro Yamada strm->zfree = zcfree; 225221b1638SMasahiro Yamada #endif 226221b1638SMasahiro Yamada state = (struct inflate_state FAR *) 227221b1638SMasahiro Yamada ZALLOC(strm, 1, sizeof(struct inflate_state)); 228221b1638SMasahiro Yamada if (state == Z_NULL) return Z_MEM_ERROR; 229221b1638SMasahiro Yamada Tracev((stderr, "inflate: allocated\n")); 230221b1638SMasahiro Yamada strm->state = (struct internal_state FAR *)state; 231221b1638SMasahiro Yamada state->strm = strm; 232221b1638SMasahiro Yamada state->window = Z_NULL; 233221b1638SMasahiro Yamada state->mode = HEAD; /* to pass state test in inflateReset2() */ 234221b1638SMasahiro Yamada ret = inflateReset2(strm, windowBits); 235221b1638SMasahiro Yamada if (ret != Z_OK) { 236221b1638SMasahiro Yamada ZFREE(strm, state); 237221b1638SMasahiro Yamada strm->state = Z_NULL; 238221b1638SMasahiro Yamada } 239221b1638SMasahiro Yamada return ret; 240221b1638SMasahiro Yamada } 241221b1638SMasahiro Yamada 242221b1638SMasahiro Yamada int ZEXPORT inflateInit_(strm, version, stream_size) 243221b1638SMasahiro Yamada z_streamp strm; 244221b1638SMasahiro Yamada const char *version; 245221b1638SMasahiro Yamada int stream_size; 246221b1638SMasahiro Yamada { 247221b1638SMasahiro Yamada return inflateInit2_(strm, DEF_WBITS, version, stream_size); 248221b1638SMasahiro Yamada } 249221b1638SMasahiro Yamada 250221b1638SMasahiro Yamada int ZEXPORT inflatePrime(strm, bits, value) 251221b1638SMasahiro Yamada z_streamp strm; 252221b1638SMasahiro Yamada int bits; 253221b1638SMasahiro Yamada int value; 254221b1638SMasahiro Yamada { 255221b1638SMasahiro Yamada struct inflate_state FAR *state; 256221b1638SMasahiro Yamada 257221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 258221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 259221b1638SMasahiro Yamada if (bits < 0) { 260221b1638SMasahiro Yamada state->hold = 0; 261221b1638SMasahiro Yamada state->bits = 0; 262221b1638SMasahiro Yamada return Z_OK; 263221b1638SMasahiro Yamada } 264221b1638SMasahiro Yamada if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; 265221b1638SMasahiro Yamada value &= (1L << bits) - 1; 266221b1638SMasahiro Yamada state->hold += (unsigned)value << state->bits; 267221b1638SMasahiro Yamada state->bits += (uInt)bits; 268221b1638SMasahiro Yamada return Z_OK; 269221b1638SMasahiro Yamada } 270221b1638SMasahiro Yamada 271221b1638SMasahiro Yamada /* 272221b1638SMasahiro Yamada Return state with length and distance decoding tables and index sizes set to 273221b1638SMasahiro Yamada fixed code decoding. Normally this returns fixed tables from inffixed.h. 274221b1638SMasahiro Yamada If BUILDFIXED is defined, then instead this routine builds the tables the 275221b1638SMasahiro Yamada first time it's called, and returns those tables the first time and 276221b1638SMasahiro Yamada thereafter. This reduces the size of the code by about 2K bytes, in 277221b1638SMasahiro Yamada exchange for a little execution time. However, BUILDFIXED should not be 278221b1638SMasahiro Yamada used for threaded applications, since the rewriting of the tables and virgin 279221b1638SMasahiro Yamada may not be thread-safe. 280221b1638SMasahiro Yamada */ 281221b1638SMasahiro Yamada local void fixedtables(state) 282221b1638SMasahiro Yamada struct inflate_state FAR *state; 283221b1638SMasahiro Yamada { 284221b1638SMasahiro Yamada #ifdef BUILDFIXED 285221b1638SMasahiro Yamada static int virgin = 1; 286221b1638SMasahiro Yamada static code *lenfix, *distfix; 287221b1638SMasahiro Yamada static code fixed[544]; 288221b1638SMasahiro Yamada 289221b1638SMasahiro Yamada /* build fixed huffman tables if first call (may not be thread safe) */ 290221b1638SMasahiro Yamada if (virgin) { 291221b1638SMasahiro Yamada unsigned sym, bits; 292221b1638SMasahiro Yamada static code *next; 293221b1638SMasahiro Yamada 294221b1638SMasahiro Yamada /* literal/length table */ 295221b1638SMasahiro Yamada sym = 0; 296221b1638SMasahiro Yamada while (sym < 144) state->lens[sym++] = 8; 297221b1638SMasahiro Yamada while (sym < 256) state->lens[sym++] = 9; 298221b1638SMasahiro Yamada while (sym < 280) state->lens[sym++] = 7; 299221b1638SMasahiro Yamada while (sym < 288) state->lens[sym++] = 8; 300221b1638SMasahiro Yamada next = fixed; 301221b1638SMasahiro Yamada lenfix = next; 302221b1638SMasahiro Yamada bits = 9; 303221b1638SMasahiro Yamada inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); 304221b1638SMasahiro Yamada 305221b1638SMasahiro Yamada /* distance table */ 306221b1638SMasahiro Yamada sym = 0; 307221b1638SMasahiro Yamada while (sym < 32) state->lens[sym++] = 5; 308221b1638SMasahiro Yamada distfix = next; 309221b1638SMasahiro Yamada bits = 5; 310221b1638SMasahiro Yamada inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); 311221b1638SMasahiro Yamada 312221b1638SMasahiro Yamada /* do this just once */ 313221b1638SMasahiro Yamada virgin = 0; 314221b1638SMasahiro Yamada } 315221b1638SMasahiro Yamada #else /* !BUILDFIXED */ 316221b1638SMasahiro Yamada # include "inffixed.h" 317221b1638SMasahiro Yamada #endif /* BUILDFIXED */ 318221b1638SMasahiro Yamada state->lencode = lenfix; 319221b1638SMasahiro Yamada state->lenbits = 9; 320221b1638SMasahiro Yamada state->distcode = distfix; 321221b1638SMasahiro Yamada state->distbits = 5; 322221b1638SMasahiro Yamada } 323221b1638SMasahiro Yamada 324221b1638SMasahiro Yamada #ifdef MAKEFIXED 325221b1638SMasahiro Yamada #include <stdio.h> 326221b1638SMasahiro Yamada 327221b1638SMasahiro Yamada /* 328221b1638SMasahiro Yamada Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also 329221b1638SMasahiro Yamada defines BUILDFIXED, so the tables are built on the fly. makefixed() writes 330221b1638SMasahiro Yamada those tables to stdout, which would be piped to inffixed.h. A small program 331221b1638SMasahiro Yamada can simply call makefixed to do this: 332221b1638SMasahiro Yamada 333221b1638SMasahiro Yamada void makefixed(void); 334221b1638SMasahiro Yamada 335221b1638SMasahiro Yamada int main(void) 336221b1638SMasahiro Yamada { 337221b1638SMasahiro Yamada makefixed(); 338221b1638SMasahiro Yamada return 0; 339221b1638SMasahiro Yamada } 340221b1638SMasahiro Yamada 341221b1638SMasahiro Yamada Then that can be linked with zlib built with MAKEFIXED defined and run: 342221b1638SMasahiro Yamada 343221b1638SMasahiro Yamada a.out > inffixed.h 344221b1638SMasahiro Yamada */ 345221b1638SMasahiro Yamada void makefixed() 346221b1638SMasahiro Yamada { 347221b1638SMasahiro Yamada unsigned low, size; 348221b1638SMasahiro Yamada struct inflate_state state; 349221b1638SMasahiro Yamada 350221b1638SMasahiro Yamada fixedtables(&state); 351221b1638SMasahiro Yamada puts(" /* inffixed.h -- table for decoding fixed codes"); 352221b1638SMasahiro Yamada puts(" * Generated automatically by makefixed()."); 353221b1638SMasahiro Yamada puts(" */"); 354221b1638SMasahiro Yamada puts(""); 355221b1638SMasahiro Yamada puts(" /* WARNING: this file should *not* be used by applications."); 356221b1638SMasahiro Yamada puts(" It is part of the implementation of this library and is"); 357221b1638SMasahiro Yamada puts(" subject to change. Applications should only use zlib.h."); 358221b1638SMasahiro Yamada puts(" */"); 359221b1638SMasahiro Yamada puts(""); 360221b1638SMasahiro Yamada size = 1U << 9; 361221b1638SMasahiro Yamada printf(" static const code lenfix[%u] = {", size); 362221b1638SMasahiro Yamada low = 0; 363221b1638SMasahiro Yamada for (;;) { 364221b1638SMasahiro Yamada if ((low % 7) == 0) printf("\n "); 365221b1638SMasahiro Yamada printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, 366221b1638SMasahiro Yamada state.lencode[low].bits, state.lencode[low].val); 367221b1638SMasahiro Yamada if (++low == size) break; 368221b1638SMasahiro Yamada putchar(','); 369221b1638SMasahiro Yamada } 370221b1638SMasahiro Yamada puts("\n };"); 371221b1638SMasahiro Yamada size = 1U << 5; 372221b1638SMasahiro Yamada printf("\n static const code distfix[%u] = {", size); 373221b1638SMasahiro Yamada low = 0; 374221b1638SMasahiro Yamada for (;;) { 375221b1638SMasahiro Yamada if ((low % 6) == 0) printf("\n "); 376221b1638SMasahiro Yamada printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, 377221b1638SMasahiro Yamada state.distcode[low].val); 378221b1638SMasahiro Yamada if (++low == size) break; 379221b1638SMasahiro Yamada putchar(','); 380221b1638SMasahiro Yamada } 381221b1638SMasahiro Yamada puts("\n };"); 382221b1638SMasahiro Yamada } 383221b1638SMasahiro Yamada #endif /* MAKEFIXED */ 384221b1638SMasahiro Yamada 385221b1638SMasahiro Yamada /* 386221b1638SMasahiro Yamada Update the window with the last wsize (normally 32K) bytes written before 387221b1638SMasahiro Yamada returning. If window does not exist yet, create it. This is only called 388221b1638SMasahiro Yamada when a window is already in use, or when output has been written during this 389221b1638SMasahiro Yamada inflate call, but the end of the deflate stream has not been reached yet. 390221b1638SMasahiro Yamada It is also called to create a window for dictionary data when a dictionary 391221b1638SMasahiro Yamada is loaded. 392221b1638SMasahiro Yamada 393221b1638SMasahiro Yamada Providing output buffers larger than 32K to inflate() should provide a speed 394221b1638SMasahiro Yamada advantage, since only the last 32K of output is copied to the sliding window 395221b1638SMasahiro Yamada upon return from inflate(), and since all distances after the first 32K of 396221b1638SMasahiro Yamada output will fall in the output data, making match copies simpler and faster. 397221b1638SMasahiro Yamada The advantage may be dependent on the size of the processor's data caches. 398221b1638SMasahiro Yamada */ 399221b1638SMasahiro Yamada local int updatewindow(strm, end, copy) 400221b1638SMasahiro Yamada z_streamp strm; 401221b1638SMasahiro Yamada const Bytef *end; 402221b1638SMasahiro Yamada unsigned copy; 403221b1638SMasahiro Yamada { 404221b1638SMasahiro Yamada struct inflate_state FAR *state; 405221b1638SMasahiro Yamada unsigned dist; 406221b1638SMasahiro Yamada 407221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 408221b1638SMasahiro Yamada 409221b1638SMasahiro Yamada /* if it hasn't been done already, allocate space for the window */ 410221b1638SMasahiro Yamada if (state->window == Z_NULL) { 411221b1638SMasahiro Yamada state->window = (unsigned char FAR *) 412221b1638SMasahiro Yamada ZALLOC(strm, 1U << state->wbits, 413221b1638SMasahiro Yamada sizeof(unsigned char)); 414221b1638SMasahiro Yamada if (state->window == Z_NULL) return 1; 415221b1638SMasahiro Yamada } 416221b1638SMasahiro Yamada 417221b1638SMasahiro Yamada /* if window not in use yet, initialize */ 418221b1638SMasahiro Yamada if (state->wsize == 0) { 419221b1638SMasahiro Yamada state->wsize = 1U << state->wbits; 420221b1638SMasahiro Yamada state->wnext = 0; 421221b1638SMasahiro Yamada state->whave = 0; 422221b1638SMasahiro Yamada } 423221b1638SMasahiro Yamada 424221b1638SMasahiro Yamada /* copy state->wsize or less output bytes into the circular window */ 425221b1638SMasahiro Yamada if (copy >= state->wsize) { 426221b1638SMasahiro Yamada zmemcpy(state->window, end - state->wsize, state->wsize); 427221b1638SMasahiro Yamada state->wnext = 0; 428221b1638SMasahiro Yamada state->whave = state->wsize; 429221b1638SMasahiro Yamada } 430221b1638SMasahiro Yamada else { 431221b1638SMasahiro Yamada dist = state->wsize - state->wnext; 432221b1638SMasahiro Yamada if (dist > copy) dist = copy; 433221b1638SMasahiro Yamada zmemcpy(state->window + state->wnext, end - copy, dist); 434221b1638SMasahiro Yamada copy -= dist; 435221b1638SMasahiro Yamada if (copy) { 436221b1638SMasahiro Yamada zmemcpy(state->window, end - copy, copy); 437221b1638SMasahiro Yamada state->wnext = copy; 438221b1638SMasahiro Yamada state->whave = state->wsize; 439221b1638SMasahiro Yamada } 440221b1638SMasahiro Yamada else { 441221b1638SMasahiro Yamada state->wnext += dist; 442221b1638SMasahiro Yamada if (state->wnext == state->wsize) state->wnext = 0; 443221b1638SMasahiro Yamada if (state->whave < state->wsize) state->whave += dist; 444221b1638SMasahiro Yamada } 445221b1638SMasahiro Yamada } 446221b1638SMasahiro Yamada return 0; 447221b1638SMasahiro Yamada } 448221b1638SMasahiro Yamada 449221b1638SMasahiro Yamada /* Macros for inflate(): */ 450221b1638SMasahiro Yamada 451221b1638SMasahiro Yamada /* check function to use adler32() for zlib or crc32() for gzip */ 452221b1638SMasahiro Yamada #ifdef GUNZIP 453*a194255dSDaniel Boulby # define UPDATE_CHECK(check, buf, len) \ 454221b1638SMasahiro Yamada (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) 455221b1638SMasahiro Yamada #else 456*a194255dSDaniel Boulby # define UPDATE_CHECK(check, buf, len) adler32(check, buf, len) 457221b1638SMasahiro Yamada #endif 458221b1638SMasahiro Yamada 459221b1638SMasahiro Yamada /* check macros for header crc */ 460221b1638SMasahiro Yamada #ifdef GUNZIP 461221b1638SMasahiro Yamada # define CRC2(check, word) \ 462221b1638SMasahiro Yamada do { \ 463221b1638SMasahiro Yamada hbuf[0] = (unsigned char)(word); \ 464221b1638SMasahiro Yamada hbuf[1] = (unsigned char)((word) >> 8); \ 465221b1638SMasahiro Yamada check = crc32(check, hbuf, 2); \ 466221b1638SMasahiro Yamada } while (0) 467221b1638SMasahiro Yamada 468221b1638SMasahiro Yamada # define CRC4(check, word) \ 469221b1638SMasahiro Yamada do { \ 470221b1638SMasahiro Yamada hbuf[0] = (unsigned char)(word); \ 471221b1638SMasahiro Yamada hbuf[1] = (unsigned char)((word) >> 8); \ 472221b1638SMasahiro Yamada hbuf[2] = (unsigned char)((word) >> 16); \ 473221b1638SMasahiro Yamada hbuf[3] = (unsigned char)((word) >> 24); \ 474221b1638SMasahiro Yamada check = crc32(check, hbuf, 4); \ 475221b1638SMasahiro Yamada } while (0) 476221b1638SMasahiro Yamada #endif 477221b1638SMasahiro Yamada 478221b1638SMasahiro Yamada /* Load registers with state in inflate() for speed */ 479221b1638SMasahiro Yamada #define LOAD() \ 480221b1638SMasahiro Yamada do { \ 481221b1638SMasahiro Yamada put = strm->next_out; \ 482221b1638SMasahiro Yamada left = strm->avail_out; \ 483221b1638SMasahiro Yamada next = strm->next_in; \ 484221b1638SMasahiro Yamada have = strm->avail_in; \ 485221b1638SMasahiro Yamada hold = state->hold; \ 486221b1638SMasahiro Yamada bits = state->bits; \ 487221b1638SMasahiro Yamada } while (0) 488221b1638SMasahiro Yamada 489221b1638SMasahiro Yamada /* Restore state from registers in inflate() */ 490221b1638SMasahiro Yamada #define RESTORE() \ 491221b1638SMasahiro Yamada do { \ 492221b1638SMasahiro Yamada strm->next_out = put; \ 493221b1638SMasahiro Yamada strm->avail_out = left; \ 494221b1638SMasahiro Yamada strm->next_in = next; \ 495221b1638SMasahiro Yamada strm->avail_in = have; \ 496221b1638SMasahiro Yamada state->hold = hold; \ 497221b1638SMasahiro Yamada state->bits = bits; \ 498221b1638SMasahiro Yamada } while (0) 499221b1638SMasahiro Yamada 500221b1638SMasahiro Yamada /* Clear the input bit accumulator */ 501221b1638SMasahiro Yamada #define INITBITS() \ 502221b1638SMasahiro Yamada do { \ 503221b1638SMasahiro Yamada hold = 0; \ 504221b1638SMasahiro Yamada bits = 0; \ 505221b1638SMasahiro Yamada } while (0) 506221b1638SMasahiro Yamada 507221b1638SMasahiro Yamada /* Get a byte of input into the bit accumulator, or return from inflate() 508221b1638SMasahiro Yamada if there is no input available. */ 509221b1638SMasahiro Yamada #define PULLBYTE() \ 510221b1638SMasahiro Yamada do { \ 511221b1638SMasahiro Yamada if (have == 0) goto inf_leave; \ 512221b1638SMasahiro Yamada have--; \ 513221b1638SMasahiro Yamada hold += (unsigned long)(*next++) << bits; \ 514221b1638SMasahiro Yamada bits += 8; \ 515221b1638SMasahiro Yamada } while (0) 516221b1638SMasahiro Yamada 517221b1638SMasahiro Yamada /* Assure that there are at least n bits in the bit accumulator. If there is 518221b1638SMasahiro Yamada not enough available input to do that, then return from inflate(). */ 519221b1638SMasahiro Yamada #define NEEDBITS(n) \ 520221b1638SMasahiro Yamada do { \ 521221b1638SMasahiro Yamada while (bits < (unsigned)(n)) \ 522221b1638SMasahiro Yamada PULLBYTE(); \ 523221b1638SMasahiro Yamada } while (0) 524221b1638SMasahiro Yamada 525221b1638SMasahiro Yamada /* Return the low n bits of the bit accumulator (n < 16) */ 526221b1638SMasahiro Yamada #define BITS(n) \ 527221b1638SMasahiro Yamada ((unsigned)hold & ((1U << (n)) - 1)) 528221b1638SMasahiro Yamada 529221b1638SMasahiro Yamada /* Remove n bits from the bit accumulator */ 530221b1638SMasahiro Yamada #define DROPBITS(n) \ 531221b1638SMasahiro Yamada do { \ 532221b1638SMasahiro Yamada hold >>= (n); \ 533221b1638SMasahiro Yamada bits -= (unsigned)(n); \ 534221b1638SMasahiro Yamada } while (0) 535221b1638SMasahiro Yamada 536221b1638SMasahiro Yamada /* Remove zero to seven bits as needed to go to a byte boundary */ 537221b1638SMasahiro Yamada #define BYTEBITS() \ 538221b1638SMasahiro Yamada do { \ 539221b1638SMasahiro Yamada hold >>= bits & 7; \ 540221b1638SMasahiro Yamada bits -= bits & 7; \ 541221b1638SMasahiro Yamada } while (0) 542221b1638SMasahiro Yamada 543221b1638SMasahiro Yamada /* 544221b1638SMasahiro Yamada inflate() uses a state machine to process as much input data and generate as 545221b1638SMasahiro Yamada much output data as possible before returning. The state machine is 546221b1638SMasahiro Yamada structured roughly as follows: 547221b1638SMasahiro Yamada 548221b1638SMasahiro Yamada for (;;) switch (state) { 549221b1638SMasahiro Yamada ... 550221b1638SMasahiro Yamada case STATEn: 551221b1638SMasahiro Yamada if (not enough input data or output space to make progress) 552221b1638SMasahiro Yamada return; 553221b1638SMasahiro Yamada ... make progress ... 554221b1638SMasahiro Yamada state = STATEm; 555221b1638SMasahiro Yamada break; 556221b1638SMasahiro Yamada ... 557221b1638SMasahiro Yamada } 558221b1638SMasahiro Yamada 559221b1638SMasahiro Yamada so when inflate() is called again, the same case is attempted again, and 560221b1638SMasahiro Yamada if the appropriate resources are provided, the machine proceeds to the 561221b1638SMasahiro Yamada next state. The NEEDBITS() macro is usually the way the state evaluates 562221b1638SMasahiro Yamada whether it can proceed or should return. NEEDBITS() does the return if 563221b1638SMasahiro Yamada the requested bits are not available. The typical use of the BITS macros 564221b1638SMasahiro Yamada is: 565221b1638SMasahiro Yamada 566221b1638SMasahiro Yamada NEEDBITS(n); 567221b1638SMasahiro Yamada ... do something with BITS(n) ... 568221b1638SMasahiro Yamada DROPBITS(n); 569221b1638SMasahiro Yamada 570221b1638SMasahiro Yamada where NEEDBITS(n) either returns from inflate() if there isn't enough 571221b1638SMasahiro Yamada input left to load n bits into the accumulator, or it continues. BITS(n) 572221b1638SMasahiro Yamada gives the low n bits in the accumulator. When done, DROPBITS(n) drops 573221b1638SMasahiro Yamada the low n bits off the accumulator. INITBITS() clears the accumulator 574221b1638SMasahiro Yamada and sets the number of available bits to zero. BYTEBITS() discards just 575221b1638SMasahiro Yamada enough bits to put the accumulator on a byte boundary. After BYTEBITS() 576221b1638SMasahiro Yamada and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. 577221b1638SMasahiro Yamada 578221b1638SMasahiro Yamada NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return 579221b1638SMasahiro Yamada if there is no input available. The decoding of variable length codes uses 580221b1638SMasahiro Yamada PULLBYTE() directly in order to pull just enough bytes to decode the next 581221b1638SMasahiro Yamada code, and no more. 582221b1638SMasahiro Yamada 583221b1638SMasahiro Yamada Some states loop until they get enough input, making sure that enough 584221b1638SMasahiro Yamada state information is maintained to continue the loop where it left off 585221b1638SMasahiro Yamada if NEEDBITS() returns in the loop. For example, want, need, and keep 586221b1638SMasahiro Yamada would all have to actually be part of the saved state in case NEEDBITS() 587221b1638SMasahiro Yamada returns: 588221b1638SMasahiro Yamada 589221b1638SMasahiro Yamada case STATEw: 590221b1638SMasahiro Yamada while (want < need) { 591221b1638SMasahiro Yamada NEEDBITS(n); 592221b1638SMasahiro Yamada keep[want++] = BITS(n); 593221b1638SMasahiro Yamada DROPBITS(n); 594221b1638SMasahiro Yamada } 595221b1638SMasahiro Yamada state = STATEx; 596221b1638SMasahiro Yamada case STATEx: 597221b1638SMasahiro Yamada 598221b1638SMasahiro Yamada As shown above, if the next state is also the next case, then the break 599221b1638SMasahiro Yamada is omitted. 600221b1638SMasahiro Yamada 601221b1638SMasahiro Yamada A state may also return if there is not enough output space available to 602221b1638SMasahiro Yamada complete that state. Those states are copying stored data, writing a 603221b1638SMasahiro Yamada literal byte, and copying a matching string. 604221b1638SMasahiro Yamada 605221b1638SMasahiro Yamada When returning, a "goto inf_leave" is used to update the total counters, 606221b1638SMasahiro Yamada update the check value, and determine whether any progress has been made 607221b1638SMasahiro Yamada during that inflate() call in order to return the proper return code. 608221b1638SMasahiro Yamada Progress is defined as a change in either strm->avail_in or strm->avail_out. 609221b1638SMasahiro Yamada When there is a window, goto inf_leave will update the window with the last 610221b1638SMasahiro Yamada output written. If a goto inf_leave occurs in the middle of decompression 611221b1638SMasahiro Yamada and there is no window currently, goto inf_leave will create one and copy 612221b1638SMasahiro Yamada output to the window for the next call of inflate(). 613221b1638SMasahiro Yamada 614221b1638SMasahiro Yamada In this implementation, the flush parameter of inflate() only affects the 615221b1638SMasahiro Yamada return code (per zlib.h). inflate() always writes as much as possible to 616221b1638SMasahiro Yamada strm->next_out, given the space available and the provided input--the effect 617221b1638SMasahiro Yamada documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers 618221b1638SMasahiro Yamada the allocation of and copying into a sliding window until necessary, which 619221b1638SMasahiro Yamada provides the effect documented in zlib.h for Z_FINISH when the entire input 620221b1638SMasahiro Yamada stream available. So the only thing the flush parameter actually does is: 621221b1638SMasahiro Yamada when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it 622221b1638SMasahiro Yamada will return Z_BUF_ERROR if it has not reached the end of the stream. 623221b1638SMasahiro Yamada */ 624221b1638SMasahiro Yamada 625221b1638SMasahiro Yamada int ZEXPORT inflate(strm, flush) 626221b1638SMasahiro Yamada z_streamp strm; 627221b1638SMasahiro Yamada int flush; 628221b1638SMasahiro Yamada { 629221b1638SMasahiro Yamada struct inflate_state FAR *state; 630221b1638SMasahiro Yamada z_const unsigned char FAR *next; /* next input */ 631221b1638SMasahiro Yamada unsigned char FAR *put; /* next output */ 632221b1638SMasahiro Yamada unsigned have, left; /* available input and output */ 633221b1638SMasahiro Yamada unsigned long hold; /* bit buffer */ 634221b1638SMasahiro Yamada unsigned bits; /* bits in bit buffer */ 635221b1638SMasahiro Yamada unsigned in, out; /* save starting available input and output */ 636221b1638SMasahiro Yamada unsigned copy; /* number of stored or match bytes to copy */ 637221b1638SMasahiro Yamada unsigned char FAR *from; /* where to copy match bytes from */ 638221b1638SMasahiro Yamada code here; /* current decoding table entry */ 639221b1638SMasahiro Yamada code last; /* parent table entry */ 640221b1638SMasahiro Yamada unsigned len; /* length to copy for repeats, bits to drop */ 641221b1638SMasahiro Yamada int ret; /* return code */ 642221b1638SMasahiro Yamada #ifdef GUNZIP 643221b1638SMasahiro Yamada unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ 644221b1638SMasahiro Yamada #endif 645221b1638SMasahiro Yamada static const unsigned short order[19] = /* permutation of code lengths */ 646221b1638SMasahiro Yamada {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 647221b1638SMasahiro Yamada 648221b1638SMasahiro Yamada if (inflateStateCheck(strm) || strm->next_out == Z_NULL || 649221b1638SMasahiro Yamada (strm->next_in == Z_NULL && strm->avail_in != 0)) 650221b1638SMasahiro Yamada return Z_STREAM_ERROR; 651221b1638SMasahiro Yamada 652221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 653221b1638SMasahiro Yamada if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ 654221b1638SMasahiro Yamada LOAD(); 655221b1638SMasahiro Yamada in = have; 656221b1638SMasahiro Yamada out = left; 657221b1638SMasahiro Yamada ret = Z_OK; 658221b1638SMasahiro Yamada for (;;) 659221b1638SMasahiro Yamada switch (state->mode) { 660221b1638SMasahiro Yamada case HEAD: 661221b1638SMasahiro Yamada if (state->wrap == 0) { 662221b1638SMasahiro Yamada state->mode = TYPEDO; 663221b1638SMasahiro Yamada break; 664221b1638SMasahiro Yamada } 665221b1638SMasahiro Yamada NEEDBITS(16); 666221b1638SMasahiro Yamada #ifdef GUNZIP 667221b1638SMasahiro Yamada if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ 668221b1638SMasahiro Yamada if (state->wbits == 0) 669221b1638SMasahiro Yamada state->wbits = 15; 670221b1638SMasahiro Yamada state->check = crc32(0L, Z_NULL, 0); 671221b1638SMasahiro Yamada CRC2(state->check, hold); 672221b1638SMasahiro Yamada INITBITS(); 673221b1638SMasahiro Yamada state->mode = FLAGS; 674221b1638SMasahiro Yamada break; 675221b1638SMasahiro Yamada } 676221b1638SMasahiro Yamada if (state->head != Z_NULL) 677221b1638SMasahiro Yamada state->head->done = -1; 678221b1638SMasahiro Yamada if (!(state->wrap & 1) || /* check if zlib header allowed */ 679221b1638SMasahiro Yamada #else 680221b1638SMasahiro Yamada if ( 681221b1638SMasahiro Yamada #endif 682221b1638SMasahiro Yamada ((BITS(8) << 8) + (hold >> 8)) % 31) { 683221b1638SMasahiro Yamada strm->msg = (char *)"incorrect header check"; 684221b1638SMasahiro Yamada state->mode = BAD; 685221b1638SMasahiro Yamada break; 686221b1638SMasahiro Yamada } 687221b1638SMasahiro Yamada if (BITS(4) != Z_DEFLATED) { 688221b1638SMasahiro Yamada strm->msg = (char *)"unknown compression method"; 689221b1638SMasahiro Yamada state->mode = BAD; 690221b1638SMasahiro Yamada break; 691221b1638SMasahiro Yamada } 692221b1638SMasahiro Yamada DROPBITS(4); 693221b1638SMasahiro Yamada len = BITS(4) + 8; 694221b1638SMasahiro Yamada if (state->wbits == 0) 695221b1638SMasahiro Yamada state->wbits = len; 696221b1638SMasahiro Yamada if (len > 15 || len > state->wbits) { 697221b1638SMasahiro Yamada strm->msg = (char *)"invalid window size"; 698221b1638SMasahiro Yamada state->mode = BAD; 699221b1638SMasahiro Yamada break; 700221b1638SMasahiro Yamada } 701221b1638SMasahiro Yamada state->dmax = 1U << len; 702*a194255dSDaniel Boulby state->flags = 0; /* indicate zlib header */ 703221b1638SMasahiro Yamada Tracev((stderr, "inflate: zlib header ok\n")); 704221b1638SMasahiro Yamada strm->adler = state->check = adler32(0L, Z_NULL, 0); 705221b1638SMasahiro Yamada state->mode = hold & 0x200 ? DICTID : TYPE; 706221b1638SMasahiro Yamada INITBITS(); 707221b1638SMasahiro Yamada break; 708221b1638SMasahiro Yamada #ifdef GUNZIP 709221b1638SMasahiro Yamada case FLAGS: 710221b1638SMasahiro Yamada NEEDBITS(16); 711221b1638SMasahiro Yamada state->flags = (int)(hold); 712221b1638SMasahiro Yamada if ((state->flags & 0xff) != Z_DEFLATED) { 713221b1638SMasahiro Yamada strm->msg = (char *)"unknown compression method"; 714221b1638SMasahiro Yamada state->mode = BAD; 715221b1638SMasahiro Yamada break; 716221b1638SMasahiro Yamada } 717221b1638SMasahiro Yamada if (state->flags & 0xe000) { 718221b1638SMasahiro Yamada strm->msg = (char *)"unknown header flags set"; 719221b1638SMasahiro Yamada state->mode = BAD; 720221b1638SMasahiro Yamada break; 721221b1638SMasahiro Yamada } 722221b1638SMasahiro Yamada if (state->head != Z_NULL) 723221b1638SMasahiro Yamada state->head->text = (int)((hold >> 8) & 1); 724221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 725221b1638SMasahiro Yamada CRC2(state->check, hold); 726221b1638SMasahiro Yamada INITBITS(); 727221b1638SMasahiro Yamada state->mode = TIME; 728*a194255dSDaniel Boulby /* fallthrough */ 729221b1638SMasahiro Yamada case TIME: 730221b1638SMasahiro Yamada NEEDBITS(32); 731221b1638SMasahiro Yamada if (state->head != Z_NULL) 732221b1638SMasahiro Yamada state->head->time = hold; 733221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 734221b1638SMasahiro Yamada CRC4(state->check, hold); 735221b1638SMasahiro Yamada INITBITS(); 736221b1638SMasahiro Yamada state->mode = OS; 737*a194255dSDaniel Boulby /* fallthrough */ 738221b1638SMasahiro Yamada case OS: 739221b1638SMasahiro Yamada NEEDBITS(16); 740221b1638SMasahiro Yamada if (state->head != Z_NULL) { 741221b1638SMasahiro Yamada state->head->xflags = (int)(hold & 0xff); 742221b1638SMasahiro Yamada state->head->os = (int)(hold >> 8); 743221b1638SMasahiro Yamada } 744221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 745221b1638SMasahiro Yamada CRC2(state->check, hold); 746221b1638SMasahiro Yamada INITBITS(); 747221b1638SMasahiro Yamada state->mode = EXLEN; 748*a194255dSDaniel Boulby /* fallthrough */ 749221b1638SMasahiro Yamada case EXLEN: 750221b1638SMasahiro Yamada if (state->flags & 0x0400) { 751221b1638SMasahiro Yamada NEEDBITS(16); 752221b1638SMasahiro Yamada state->length = (unsigned)(hold); 753221b1638SMasahiro Yamada if (state->head != Z_NULL) 754221b1638SMasahiro Yamada state->head->extra_len = (unsigned)hold; 755221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 756221b1638SMasahiro Yamada CRC2(state->check, hold); 757221b1638SMasahiro Yamada INITBITS(); 758221b1638SMasahiro Yamada } 759221b1638SMasahiro Yamada else if (state->head != Z_NULL) 760221b1638SMasahiro Yamada state->head->extra = Z_NULL; 761221b1638SMasahiro Yamada state->mode = EXTRA; 762*a194255dSDaniel Boulby /* fallthrough */ 763221b1638SMasahiro Yamada case EXTRA: 764221b1638SMasahiro Yamada if (state->flags & 0x0400) { 765221b1638SMasahiro Yamada copy = state->length; 766221b1638SMasahiro Yamada if (copy > have) copy = have; 767221b1638SMasahiro Yamada if (copy) { 768221b1638SMasahiro Yamada if (state->head != Z_NULL && 769*a194255dSDaniel Boulby state->head->extra != Z_NULL && 770*a194255dSDaniel Boulby (len = state->head->extra_len - state->length) < 771*a194255dSDaniel Boulby state->head->extra_max) { 772221b1638SMasahiro Yamada zmemcpy(state->head->extra + len, next, 773221b1638SMasahiro Yamada len + copy > state->head->extra_max ? 774221b1638SMasahiro Yamada state->head->extra_max - len : copy); 775221b1638SMasahiro Yamada } 776221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 777221b1638SMasahiro Yamada state->check = crc32(state->check, next, copy); 778221b1638SMasahiro Yamada have -= copy; 779221b1638SMasahiro Yamada next += copy; 780221b1638SMasahiro Yamada state->length -= copy; 781221b1638SMasahiro Yamada } 782221b1638SMasahiro Yamada if (state->length) goto inf_leave; 783221b1638SMasahiro Yamada } 784221b1638SMasahiro Yamada state->length = 0; 785221b1638SMasahiro Yamada state->mode = NAME; 786*a194255dSDaniel Boulby /* fallthrough */ 787221b1638SMasahiro Yamada case NAME: 788221b1638SMasahiro Yamada if (state->flags & 0x0800) { 789221b1638SMasahiro Yamada if (have == 0) goto inf_leave; 790221b1638SMasahiro Yamada copy = 0; 791221b1638SMasahiro Yamada do { 792221b1638SMasahiro Yamada len = (unsigned)(next[copy++]); 793221b1638SMasahiro Yamada if (state->head != Z_NULL && 794221b1638SMasahiro Yamada state->head->name != Z_NULL && 795221b1638SMasahiro Yamada state->length < state->head->name_max) 796221b1638SMasahiro Yamada state->head->name[state->length++] = (Bytef)len; 797221b1638SMasahiro Yamada } while (len && copy < have); 798221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 799221b1638SMasahiro Yamada state->check = crc32(state->check, next, copy); 800221b1638SMasahiro Yamada have -= copy; 801221b1638SMasahiro Yamada next += copy; 802221b1638SMasahiro Yamada if (len) goto inf_leave; 803221b1638SMasahiro Yamada } 804221b1638SMasahiro Yamada else if (state->head != Z_NULL) 805221b1638SMasahiro Yamada state->head->name = Z_NULL; 806221b1638SMasahiro Yamada state->length = 0; 807221b1638SMasahiro Yamada state->mode = COMMENT; 808*a194255dSDaniel Boulby /* fallthrough */ 809221b1638SMasahiro Yamada case COMMENT: 810221b1638SMasahiro Yamada if (state->flags & 0x1000) { 811221b1638SMasahiro Yamada if (have == 0) goto inf_leave; 812221b1638SMasahiro Yamada copy = 0; 813221b1638SMasahiro Yamada do { 814221b1638SMasahiro Yamada len = (unsigned)(next[copy++]); 815221b1638SMasahiro Yamada if (state->head != Z_NULL && 816221b1638SMasahiro Yamada state->head->comment != Z_NULL && 817221b1638SMasahiro Yamada state->length < state->head->comm_max) 818221b1638SMasahiro Yamada state->head->comment[state->length++] = (Bytef)len; 819221b1638SMasahiro Yamada } while (len && copy < have); 820221b1638SMasahiro Yamada if ((state->flags & 0x0200) && (state->wrap & 4)) 821221b1638SMasahiro Yamada state->check = crc32(state->check, next, copy); 822221b1638SMasahiro Yamada have -= copy; 823221b1638SMasahiro Yamada next += copy; 824221b1638SMasahiro Yamada if (len) goto inf_leave; 825221b1638SMasahiro Yamada } 826221b1638SMasahiro Yamada else if (state->head != Z_NULL) 827221b1638SMasahiro Yamada state->head->comment = Z_NULL; 828221b1638SMasahiro Yamada state->mode = HCRC; 829*a194255dSDaniel Boulby /* fallthrough */ 830221b1638SMasahiro Yamada case HCRC: 831221b1638SMasahiro Yamada if (state->flags & 0x0200) { 832221b1638SMasahiro Yamada NEEDBITS(16); 833221b1638SMasahiro Yamada if ((state->wrap & 4) && hold != (state->check & 0xffff)) { 834221b1638SMasahiro Yamada strm->msg = (char *)"header crc mismatch"; 835221b1638SMasahiro Yamada state->mode = BAD; 836221b1638SMasahiro Yamada break; 837221b1638SMasahiro Yamada } 838221b1638SMasahiro Yamada INITBITS(); 839221b1638SMasahiro Yamada } 840221b1638SMasahiro Yamada if (state->head != Z_NULL) { 841221b1638SMasahiro Yamada state->head->hcrc = (int)((state->flags >> 9) & 1); 842221b1638SMasahiro Yamada state->head->done = 1; 843221b1638SMasahiro Yamada } 844221b1638SMasahiro Yamada strm->adler = state->check = crc32(0L, Z_NULL, 0); 845221b1638SMasahiro Yamada state->mode = TYPE; 846221b1638SMasahiro Yamada break; 847221b1638SMasahiro Yamada #endif 848221b1638SMasahiro Yamada case DICTID: 849221b1638SMasahiro Yamada NEEDBITS(32); 850221b1638SMasahiro Yamada strm->adler = state->check = ZSWAP32(hold); 851221b1638SMasahiro Yamada INITBITS(); 852221b1638SMasahiro Yamada state->mode = DICT; 853*a194255dSDaniel Boulby /* fallthrough */ 854221b1638SMasahiro Yamada case DICT: 855221b1638SMasahiro Yamada if (state->havedict == 0) { 856221b1638SMasahiro Yamada RESTORE(); 857221b1638SMasahiro Yamada return Z_NEED_DICT; 858221b1638SMasahiro Yamada } 859221b1638SMasahiro Yamada strm->adler = state->check = adler32(0L, Z_NULL, 0); 860221b1638SMasahiro Yamada state->mode = TYPE; 861*a194255dSDaniel Boulby /* fallthrough */ 862221b1638SMasahiro Yamada case TYPE: 863221b1638SMasahiro Yamada if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; 864*a194255dSDaniel Boulby /* fallthrough */ 865221b1638SMasahiro Yamada case TYPEDO: 866221b1638SMasahiro Yamada if (state->last) { 867221b1638SMasahiro Yamada BYTEBITS(); 868221b1638SMasahiro Yamada state->mode = CHECK; 869221b1638SMasahiro Yamada break; 870221b1638SMasahiro Yamada } 871221b1638SMasahiro Yamada NEEDBITS(3); 872221b1638SMasahiro Yamada state->last = BITS(1); 873221b1638SMasahiro Yamada DROPBITS(1); 874221b1638SMasahiro Yamada switch (BITS(2)) { 875221b1638SMasahiro Yamada case 0: /* stored block */ 876221b1638SMasahiro Yamada Tracev((stderr, "inflate: stored block%s\n", 877221b1638SMasahiro Yamada state->last ? " (last)" : "")); 878221b1638SMasahiro Yamada state->mode = STORED; 879221b1638SMasahiro Yamada break; 880221b1638SMasahiro Yamada case 1: /* fixed block */ 881221b1638SMasahiro Yamada fixedtables(state); 882221b1638SMasahiro Yamada Tracev((stderr, "inflate: fixed codes block%s\n", 883221b1638SMasahiro Yamada state->last ? " (last)" : "")); 884221b1638SMasahiro Yamada state->mode = LEN_; /* decode codes */ 885221b1638SMasahiro Yamada if (flush == Z_TREES) { 886221b1638SMasahiro Yamada DROPBITS(2); 887221b1638SMasahiro Yamada goto inf_leave; 888221b1638SMasahiro Yamada } 889221b1638SMasahiro Yamada break; 890221b1638SMasahiro Yamada case 2: /* dynamic block */ 891221b1638SMasahiro Yamada Tracev((stderr, "inflate: dynamic codes block%s\n", 892221b1638SMasahiro Yamada state->last ? " (last)" : "")); 893221b1638SMasahiro Yamada state->mode = TABLE; 894221b1638SMasahiro Yamada break; 895221b1638SMasahiro Yamada case 3: 896221b1638SMasahiro Yamada strm->msg = (char *)"invalid block type"; 897221b1638SMasahiro Yamada state->mode = BAD; 898221b1638SMasahiro Yamada } 899221b1638SMasahiro Yamada DROPBITS(2); 900221b1638SMasahiro Yamada break; 901221b1638SMasahiro Yamada case STORED: 902221b1638SMasahiro Yamada BYTEBITS(); /* go to byte boundary */ 903221b1638SMasahiro Yamada NEEDBITS(32); 904221b1638SMasahiro Yamada if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { 905221b1638SMasahiro Yamada strm->msg = (char *)"invalid stored block lengths"; 906221b1638SMasahiro Yamada state->mode = BAD; 907221b1638SMasahiro Yamada break; 908221b1638SMasahiro Yamada } 909221b1638SMasahiro Yamada state->length = (unsigned)hold & 0xffff; 910221b1638SMasahiro Yamada Tracev((stderr, "inflate: stored length %u\n", 911221b1638SMasahiro Yamada state->length)); 912221b1638SMasahiro Yamada INITBITS(); 913221b1638SMasahiro Yamada state->mode = COPY_; 914221b1638SMasahiro Yamada if (flush == Z_TREES) goto inf_leave; 915*a194255dSDaniel Boulby /* fallthrough */ 916221b1638SMasahiro Yamada case COPY_: 917221b1638SMasahiro Yamada state->mode = COPY; 918*a194255dSDaniel Boulby /* fallthrough */ 919221b1638SMasahiro Yamada case COPY: 920221b1638SMasahiro Yamada copy = state->length; 921221b1638SMasahiro Yamada if (copy) { 922221b1638SMasahiro Yamada if (copy > have) copy = have; 923221b1638SMasahiro Yamada if (copy > left) copy = left; 924221b1638SMasahiro Yamada if (copy == 0) goto inf_leave; 925221b1638SMasahiro Yamada zmemcpy(put, next, copy); 926221b1638SMasahiro Yamada have -= copy; 927221b1638SMasahiro Yamada next += copy; 928221b1638SMasahiro Yamada left -= copy; 929221b1638SMasahiro Yamada put += copy; 930221b1638SMasahiro Yamada state->length -= copy; 931221b1638SMasahiro Yamada break; 932221b1638SMasahiro Yamada } 933221b1638SMasahiro Yamada Tracev((stderr, "inflate: stored end\n")); 934221b1638SMasahiro Yamada state->mode = TYPE; 935221b1638SMasahiro Yamada break; 936221b1638SMasahiro Yamada case TABLE: 937221b1638SMasahiro Yamada NEEDBITS(14); 938221b1638SMasahiro Yamada state->nlen = BITS(5) + 257; 939221b1638SMasahiro Yamada DROPBITS(5); 940221b1638SMasahiro Yamada state->ndist = BITS(5) + 1; 941221b1638SMasahiro Yamada DROPBITS(5); 942221b1638SMasahiro Yamada state->ncode = BITS(4) + 4; 943221b1638SMasahiro Yamada DROPBITS(4); 944221b1638SMasahiro Yamada #ifndef PKZIP_BUG_WORKAROUND 945221b1638SMasahiro Yamada if (state->nlen > 286 || state->ndist > 30) { 946221b1638SMasahiro Yamada strm->msg = (char *)"too many length or distance symbols"; 947221b1638SMasahiro Yamada state->mode = BAD; 948221b1638SMasahiro Yamada break; 949221b1638SMasahiro Yamada } 950221b1638SMasahiro Yamada #endif 951221b1638SMasahiro Yamada Tracev((stderr, "inflate: table sizes ok\n")); 952221b1638SMasahiro Yamada state->have = 0; 953221b1638SMasahiro Yamada state->mode = LENLENS; 954*a194255dSDaniel Boulby /* fallthrough */ 955221b1638SMasahiro Yamada case LENLENS: 956221b1638SMasahiro Yamada while (state->have < state->ncode) { 957221b1638SMasahiro Yamada NEEDBITS(3); 958221b1638SMasahiro Yamada state->lens[order[state->have++]] = (unsigned short)BITS(3); 959221b1638SMasahiro Yamada DROPBITS(3); 960221b1638SMasahiro Yamada } 961221b1638SMasahiro Yamada while (state->have < 19) 962221b1638SMasahiro Yamada state->lens[order[state->have++]] = 0; 963221b1638SMasahiro Yamada state->next = state->codes; 964221b1638SMasahiro Yamada state->lencode = (const code FAR *)(state->next); 965221b1638SMasahiro Yamada state->lenbits = 7; 966221b1638SMasahiro Yamada ret = inflate_table(CODES, state->lens, 19, &(state->next), 967221b1638SMasahiro Yamada &(state->lenbits), state->work); 968221b1638SMasahiro Yamada if (ret) { 969221b1638SMasahiro Yamada strm->msg = (char *)"invalid code lengths set"; 970221b1638SMasahiro Yamada state->mode = BAD; 971221b1638SMasahiro Yamada break; 972221b1638SMasahiro Yamada } 973221b1638SMasahiro Yamada Tracev((stderr, "inflate: code lengths ok\n")); 974221b1638SMasahiro Yamada state->have = 0; 975221b1638SMasahiro Yamada state->mode = CODELENS; 976*a194255dSDaniel Boulby /* fallthrough */ 977221b1638SMasahiro Yamada case CODELENS: 978221b1638SMasahiro Yamada while (state->have < state->nlen + state->ndist) { 979221b1638SMasahiro Yamada for (;;) { 980221b1638SMasahiro Yamada here = state->lencode[BITS(state->lenbits)]; 981221b1638SMasahiro Yamada if ((unsigned)(here.bits) <= bits) break; 982221b1638SMasahiro Yamada PULLBYTE(); 983221b1638SMasahiro Yamada } 984221b1638SMasahiro Yamada if (here.val < 16) { 985221b1638SMasahiro Yamada DROPBITS(here.bits); 986221b1638SMasahiro Yamada state->lens[state->have++] = here.val; 987221b1638SMasahiro Yamada } 988221b1638SMasahiro Yamada else { 989221b1638SMasahiro Yamada if (here.val == 16) { 990221b1638SMasahiro Yamada NEEDBITS(here.bits + 2); 991221b1638SMasahiro Yamada DROPBITS(here.bits); 992221b1638SMasahiro Yamada if (state->have == 0) { 993221b1638SMasahiro Yamada strm->msg = (char *)"invalid bit length repeat"; 994221b1638SMasahiro Yamada state->mode = BAD; 995221b1638SMasahiro Yamada break; 996221b1638SMasahiro Yamada } 997221b1638SMasahiro Yamada len = state->lens[state->have - 1]; 998221b1638SMasahiro Yamada copy = 3 + BITS(2); 999221b1638SMasahiro Yamada DROPBITS(2); 1000221b1638SMasahiro Yamada } 1001221b1638SMasahiro Yamada else if (here.val == 17) { 1002221b1638SMasahiro Yamada NEEDBITS(here.bits + 3); 1003221b1638SMasahiro Yamada DROPBITS(here.bits); 1004221b1638SMasahiro Yamada len = 0; 1005221b1638SMasahiro Yamada copy = 3 + BITS(3); 1006221b1638SMasahiro Yamada DROPBITS(3); 1007221b1638SMasahiro Yamada } 1008221b1638SMasahiro Yamada else { 1009221b1638SMasahiro Yamada NEEDBITS(here.bits + 7); 1010221b1638SMasahiro Yamada DROPBITS(here.bits); 1011221b1638SMasahiro Yamada len = 0; 1012221b1638SMasahiro Yamada copy = 11 + BITS(7); 1013221b1638SMasahiro Yamada DROPBITS(7); 1014221b1638SMasahiro Yamada } 1015221b1638SMasahiro Yamada if (state->have + copy > state->nlen + state->ndist) { 1016221b1638SMasahiro Yamada strm->msg = (char *)"invalid bit length repeat"; 1017221b1638SMasahiro Yamada state->mode = BAD; 1018221b1638SMasahiro Yamada break; 1019221b1638SMasahiro Yamada } 1020221b1638SMasahiro Yamada while (copy--) 1021221b1638SMasahiro Yamada state->lens[state->have++] = (unsigned short)len; 1022221b1638SMasahiro Yamada } 1023221b1638SMasahiro Yamada } 1024221b1638SMasahiro Yamada 1025221b1638SMasahiro Yamada /* handle error breaks in while */ 1026221b1638SMasahiro Yamada if (state->mode == BAD) break; 1027221b1638SMasahiro Yamada 1028221b1638SMasahiro Yamada /* check for end-of-block code (better have one) */ 1029221b1638SMasahiro Yamada if (state->lens[256] == 0) { 1030221b1638SMasahiro Yamada strm->msg = (char *)"invalid code -- missing end-of-block"; 1031221b1638SMasahiro Yamada state->mode = BAD; 1032221b1638SMasahiro Yamada break; 1033221b1638SMasahiro Yamada } 1034221b1638SMasahiro Yamada 1035221b1638SMasahiro Yamada /* build code tables -- note: do not change the lenbits or distbits 1036221b1638SMasahiro Yamada values here (9 and 6) without reading the comments in inftrees.h 1037221b1638SMasahiro Yamada concerning the ENOUGH constants, which depend on those values */ 1038221b1638SMasahiro Yamada state->next = state->codes; 1039221b1638SMasahiro Yamada state->lencode = (const code FAR *)(state->next); 1040221b1638SMasahiro Yamada state->lenbits = 9; 1041221b1638SMasahiro Yamada ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), 1042221b1638SMasahiro Yamada &(state->lenbits), state->work); 1043221b1638SMasahiro Yamada if (ret) { 1044221b1638SMasahiro Yamada strm->msg = (char *)"invalid literal/lengths set"; 1045221b1638SMasahiro Yamada state->mode = BAD; 1046221b1638SMasahiro Yamada break; 1047221b1638SMasahiro Yamada } 1048221b1638SMasahiro Yamada state->distcode = (const code FAR *)(state->next); 1049221b1638SMasahiro Yamada state->distbits = 6; 1050221b1638SMasahiro Yamada ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, 1051221b1638SMasahiro Yamada &(state->next), &(state->distbits), state->work); 1052221b1638SMasahiro Yamada if (ret) { 1053221b1638SMasahiro Yamada strm->msg = (char *)"invalid distances set"; 1054221b1638SMasahiro Yamada state->mode = BAD; 1055221b1638SMasahiro Yamada break; 1056221b1638SMasahiro Yamada } 1057221b1638SMasahiro Yamada Tracev((stderr, "inflate: codes ok\n")); 1058221b1638SMasahiro Yamada state->mode = LEN_; 1059221b1638SMasahiro Yamada if (flush == Z_TREES) goto inf_leave; 1060*a194255dSDaniel Boulby /* fallthrough */ 1061221b1638SMasahiro Yamada case LEN_: 1062221b1638SMasahiro Yamada state->mode = LEN; 1063*a194255dSDaniel Boulby /* fallthrough */ 1064221b1638SMasahiro Yamada case LEN: 1065221b1638SMasahiro Yamada if (have >= 6 && left >= 258) { 1066221b1638SMasahiro Yamada RESTORE(); 1067221b1638SMasahiro Yamada inflate_fast(strm, out); 1068221b1638SMasahiro Yamada LOAD(); 1069221b1638SMasahiro Yamada if (state->mode == TYPE) 1070221b1638SMasahiro Yamada state->back = -1; 1071221b1638SMasahiro Yamada break; 1072221b1638SMasahiro Yamada } 1073221b1638SMasahiro Yamada state->back = 0; 1074221b1638SMasahiro Yamada for (;;) { 1075221b1638SMasahiro Yamada here = state->lencode[BITS(state->lenbits)]; 1076221b1638SMasahiro Yamada if ((unsigned)(here.bits) <= bits) break; 1077221b1638SMasahiro Yamada PULLBYTE(); 1078221b1638SMasahiro Yamada } 1079221b1638SMasahiro Yamada if (here.op && (here.op & 0xf0) == 0) { 1080221b1638SMasahiro Yamada last = here; 1081221b1638SMasahiro Yamada for (;;) { 1082221b1638SMasahiro Yamada here = state->lencode[last.val + 1083221b1638SMasahiro Yamada (BITS(last.bits + last.op) >> last.bits)]; 1084221b1638SMasahiro Yamada if ((unsigned)(last.bits + here.bits) <= bits) break; 1085221b1638SMasahiro Yamada PULLBYTE(); 1086221b1638SMasahiro Yamada } 1087221b1638SMasahiro Yamada DROPBITS(last.bits); 1088221b1638SMasahiro Yamada state->back += last.bits; 1089221b1638SMasahiro Yamada } 1090221b1638SMasahiro Yamada DROPBITS(here.bits); 1091221b1638SMasahiro Yamada state->back += here.bits; 1092221b1638SMasahiro Yamada state->length = (unsigned)here.val; 1093221b1638SMasahiro Yamada if ((int)(here.op) == 0) { 1094221b1638SMasahiro Yamada Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 1095221b1638SMasahiro Yamada "inflate: literal '%c'\n" : 1096221b1638SMasahiro Yamada "inflate: literal 0x%02x\n", here.val)); 1097221b1638SMasahiro Yamada state->mode = LIT; 1098221b1638SMasahiro Yamada break; 1099221b1638SMasahiro Yamada } 1100221b1638SMasahiro Yamada if (here.op & 32) { 1101221b1638SMasahiro Yamada Tracevv((stderr, "inflate: end of block\n")); 1102221b1638SMasahiro Yamada state->back = -1; 1103221b1638SMasahiro Yamada state->mode = TYPE; 1104221b1638SMasahiro Yamada break; 1105221b1638SMasahiro Yamada } 1106221b1638SMasahiro Yamada if (here.op & 64) { 1107221b1638SMasahiro Yamada strm->msg = (char *)"invalid literal/length code"; 1108221b1638SMasahiro Yamada state->mode = BAD; 1109221b1638SMasahiro Yamada break; 1110221b1638SMasahiro Yamada } 1111221b1638SMasahiro Yamada state->extra = (unsigned)(here.op) & 15; 1112221b1638SMasahiro Yamada state->mode = LENEXT; 1113*a194255dSDaniel Boulby /* fallthrough */ 1114221b1638SMasahiro Yamada case LENEXT: 1115221b1638SMasahiro Yamada if (state->extra) { 1116221b1638SMasahiro Yamada NEEDBITS(state->extra); 1117221b1638SMasahiro Yamada state->length += BITS(state->extra); 1118221b1638SMasahiro Yamada DROPBITS(state->extra); 1119221b1638SMasahiro Yamada state->back += state->extra; 1120221b1638SMasahiro Yamada } 1121221b1638SMasahiro Yamada Tracevv((stderr, "inflate: length %u\n", state->length)); 1122221b1638SMasahiro Yamada state->was = state->length; 1123221b1638SMasahiro Yamada state->mode = DIST; 1124*a194255dSDaniel Boulby /* fallthrough */ 1125221b1638SMasahiro Yamada case DIST: 1126221b1638SMasahiro Yamada for (;;) { 1127221b1638SMasahiro Yamada here = state->distcode[BITS(state->distbits)]; 1128221b1638SMasahiro Yamada if ((unsigned)(here.bits) <= bits) break; 1129221b1638SMasahiro Yamada PULLBYTE(); 1130221b1638SMasahiro Yamada } 1131221b1638SMasahiro Yamada if ((here.op & 0xf0) == 0) { 1132221b1638SMasahiro Yamada last = here; 1133221b1638SMasahiro Yamada for (;;) { 1134221b1638SMasahiro Yamada here = state->distcode[last.val + 1135221b1638SMasahiro Yamada (BITS(last.bits + last.op) >> last.bits)]; 1136221b1638SMasahiro Yamada if ((unsigned)(last.bits + here.bits) <= bits) break; 1137221b1638SMasahiro Yamada PULLBYTE(); 1138221b1638SMasahiro Yamada } 1139221b1638SMasahiro Yamada DROPBITS(last.bits); 1140221b1638SMasahiro Yamada state->back += last.bits; 1141221b1638SMasahiro Yamada } 1142221b1638SMasahiro Yamada DROPBITS(here.bits); 1143221b1638SMasahiro Yamada state->back += here.bits; 1144221b1638SMasahiro Yamada if (here.op & 64) { 1145221b1638SMasahiro Yamada strm->msg = (char *)"invalid distance code"; 1146221b1638SMasahiro Yamada state->mode = BAD; 1147221b1638SMasahiro Yamada break; 1148221b1638SMasahiro Yamada } 1149221b1638SMasahiro Yamada state->offset = (unsigned)here.val; 1150221b1638SMasahiro Yamada state->extra = (unsigned)(here.op) & 15; 1151221b1638SMasahiro Yamada state->mode = DISTEXT; 1152*a194255dSDaniel Boulby /* fallthrough */ 1153221b1638SMasahiro Yamada case DISTEXT: 1154221b1638SMasahiro Yamada if (state->extra) { 1155221b1638SMasahiro Yamada NEEDBITS(state->extra); 1156221b1638SMasahiro Yamada state->offset += BITS(state->extra); 1157221b1638SMasahiro Yamada DROPBITS(state->extra); 1158221b1638SMasahiro Yamada state->back += state->extra; 1159221b1638SMasahiro Yamada } 1160221b1638SMasahiro Yamada #ifdef INFLATE_STRICT 1161221b1638SMasahiro Yamada if (state->offset > state->dmax) { 1162221b1638SMasahiro Yamada strm->msg = (char *)"invalid distance too far back"; 1163221b1638SMasahiro Yamada state->mode = BAD; 1164221b1638SMasahiro Yamada break; 1165221b1638SMasahiro Yamada } 1166221b1638SMasahiro Yamada #endif 1167221b1638SMasahiro Yamada Tracevv((stderr, "inflate: distance %u\n", state->offset)); 1168221b1638SMasahiro Yamada state->mode = MATCH; 1169*a194255dSDaniel Boulby /* fallthrough */ 1170221b1638SMasahiro Yamada case MATCH: 1171221b1638SMasahiro Yamada if (left == 0) goto inf_leave; 1172221b1638SMasahiro Yamada copy = out - left; 1173221b1638SMasahiro Yamada if (state->offset > copy) { /* copy from window */ 1174221b1638SMasahiro Yamada copy = state->offset - copy; 1175221b1638SMasahiro Yamada if (copy > state->whave) { 1176221b1638SMasahiro Yamada if (state->sane) { 1177221b1638SMasahiro Yamada strm->msg = (char *)"invalid distance too far back"; 1178221b1638SMasahiro Yamada state->mode = BAD; 1179221b1638SMasahiro Yamada break; 1180221b1638SMasahiro Yamada } 1181221b1638SMasahiro Yamada #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 1182221b1638SMasahiro Yamada Trace((stderr, "inflate.c too far\n")); 1183221b1638SMasahiro Yamada copy -= state->whave; 1184221b1638SMasahiro Yamada if (copy > state->length) copy = state->length; 1185221b1638SMasahiro Yamada if (copy > left) copy = left; 1186221b1638SMasahiro Yamada left -= copy; 1187221b1638SMasahiro Yamada state->length -= copy; 1188221b1638SMasahiro Yamada do { 1189221b1638SMasahiro Yamada *put++ = 0; 1190221b1638SMasahiro Yamada } while (--copy); 1191221b1638SMasahiro Yamada if (state->length == 0) state->mode = LEN; 1192221b1638SMasahiro Yamada break; 1193221b1638SMasahiro Yamada #endif 1194221b1638SMasahiro Yamada } 1195221b1638SMasahiro Yamada if (copy > state->wnext) { 1196221b1638SMasahiro Yamada copy -= state->wnext; 1197221b1638SMasahiro Yamada from = state->window + (state->wsize - copy); 1198221b1638SMasahiro Yamada } 1199221b1638SMasahiro Yamada else 1200221b1638SMasahiro Yamada from = state->window + (state->wnext - copy); 1201221b1638SMasahiro Yamada if (copy > state->length) copy = state->length; 1202221b1638SMasahiro Yamada } 1203221b1638SMasahiro Yamada else { /* copy from output */ 1204221b1638SMasahiro Yamada from = put - state->offset; 1205221b1638SMasahiro Yamada copy = state->length; 1206221b1638SMasahiro Yamada } 1207221b1638SMasahiro Yamada if (copy > left) copy = left; 1208221b1638SMasahiro Yamada left -= copy; 1209221b1638SMasahiro Yamada state->length -= copy; 1210221b1638SMasahiro Yamada do { 1211221b1638SMasahiro Yamada *put++ = *from++; 1212221b1638SMasahiro Yamada } while (--copy); 1213221b1638SMasahiro Yamada if (state->length == 0) state->mode = LEN; 1214221b1638SMasahiro Yamada break; 1215221b1638SMasahiro Yamada case LIT: 1216221b1638SMasahiro Yamada if (left == 0) goto inf_leave; 1217221b1638SMasahiro Yamada *put++ = (unsigned char)(state->length); 1218221b1638SMasahiro Yamada left--; 1219221b1638SMasahiro Yamada state->mode = LEN; 1220221b1638SMasahiro Yamada break; 1221221b1638SMasahiro Yamada case CHECK: 1222221b1638SMasahiro Yamada if (state->wrap) { 1223221b1638SMasahiro Yamada NEEDBITS(32); 1224221b1638SMasahiro Yamada out -= left; 1225221b1638SMasahiro Yamada strm->total_out += out; 1226221b1638SMasahiro Yamada state->total += out; 1227221b1638SMasahiro Yamada if ((state->wrap & 4) && out) 1228221b1638SMasahiro Yamada strm->adler = state->check = 1229*a194255dSDaniel Boulby UPDATE_CHECK(state->check, put - out, out); 1230221b1638SMasahiro Yamada out = left; 1231221b1638SMasahiro Yamada if ((state->wrap & 4) && ( 1232221b1638SMasahiro Yamada #ifdef GUNZIP 1233221b1638SMasahiro Yamada state->flags ? hold : 1234221b1638SMasahiro Yamada #endif 1235221b1638SMasahiro Yamada ZSWAP32(hold)) != state->check) { 1236221b1638SMasahiro Yamada strm->msg = (char *)"incorrect data check"; 1237221b1638SMasahiro Yamada state->mode = BAD; 1238221b1638SMasahiro Yamada break; 1239221b1638SMasahiro Yamada } 1240221b1638SMasahiro Yamada INITBITS(); 1241221b1638SMasahiro Yamada Tracev((stderr, "inflate: check matches trailer\n")); 1242221b1638SMasahiro Yamada } 1243221b1638SMasahiro Yamada #ifdef GUNZIP 1244221b1638SMasahiro Yamada state->mode = LENGTH; 1245*a194255dSDaniel Boulby /* fallthrough */ 1246221b1638SMasahiro Yamada case LENGTH: 1247221b1638SMasahiro Yamada if (state->wrap && state->flags) { 1248221b1638SMasahiro Yamada NEEDBITS(32); 1249*a194255dSDaniel Boulby if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { 1250221b1638SMasahiro Yamada strm->msg = (char *)"incorrect length check"; 1251221b1638SMasahiro Yamada state->mode = BAD; 1252221b1638SMasahiro Yamada break; 1253221b1638SMasahiro Yamada } 1254221b1638SMasahiro Yamada INITBITS(); 1255221b1638SMasahiro Yamada Tracev((stderr, "inflate: length matches trailer\n")); 1256221b1638SMasahiro Yamada } 1257221b1638SMasahiro Yamada #endif 1258221b1638SMasahiro Yamada state->mode = DONE; 1259*a194255dSDaniel Boulby /* fallthrough */ 1260221b1638SMasahiro Yamada case DONE: 1261221b1638SMasahiro Yamada ret = Z_STREAM_END; 1262221b1638SMasahiro Yamada goto inf_leave; 1263221b1638SMasahiro Yamada case BAD: 1264221b1638SMasahiro Yamada ret = Z_DATA_ERROR; 1265221b1638SMasahiro Yamada goto inf_leave; 1266221b1638SMasahiro Yamada case MEM: 1267221b1638SMasahiro Yamada return Z_MEM_ERROR; 1268221b1638SMasahiro Yamada case SYNC: 1269*a194255dSDaniel Boulby /* fallthrough */ 1270221b1638SMasahiro Yamada default: 1271221b1638SMasahiro Yamada return Z_STREAM_ERROR; 1272221b1638SMasahiro Yamada } 1273221b1638SMasahiro Yamada 1274221b1638SMasahiro Yamada /* 1275221b1638SMasahiro Yamada Return from inflate(), updating the total counts and the check value. 1276221b1638SMasahiro Yamada If there was no progress during the inflate() call, return a buffer 1277221b1638SMasahiro Yamada error. Call updatewindow() to create and/or update the window state. 1278221b1638SMasahiro Yamada Note: a memory error from inflate() is non-recoverable. 1279221b1638SMasahiro Yamada */ 1280221b1638SMasahiro Yamada inf_leave: 1281221b1638SMasahiro Yamada RESTORE(); 1282221b1638SMasahiro Yamada if (state->wsize || (out != strm->avail_out && state->mode < BAD && 1283221b1638SMasahiro Yamada (state->mode < CHECK || flush != Z_FINISH))) 1284221b1638SMasahiro Yamada if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { 1285221b1638SMasahiro Yamada state->mode = MEM; 1286221b1638SMasahiro Yamada return Z_MEM_ERROR; 1287221b1638SMasahiro Yamada } 1288221b1638SMasahiro Yamada in -= strm->avail_in; 1289221b1638SMasahiro Yamada out -= strm->avail_out; 1290221b1638SMasahiro Yamada strm->total_in += in; 1291221b1638SMasahiro Yamada strm->total_out += out; 1292221b1638SMasahiro Yamada state->total += out; 1293221b1638SMasahiro Yamada if ((state->wrap & 4) && out) 1294221b1638SMasahiro Yamada strm->adler = state->check = 1295*a194255dSDaniel Boulby UPDATE_CHECK(state->check, strm->next_out - out, out); 1296221b1638SMasahiro Yamada strm->data_type = (int)state->bits + (state->last ? 64 : 0) + 1297221b1638SMasahiro Yamada (state->mode == TYPE ? 128 : 0) + 1298221b1638SMasahiro Yamada (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); 1299221b1638SMasahiro Yamada if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) 1300221b1638SMasahiro Yamada ret = Z_BUF_ERROR; 1301221b1638SMasahiro Yamada return ret; 1302221b1638SMasahiro Yamada } 1303221b1638SMasahiro Yamada 1304221b1638SMasahiro Yamada int ZEXPORT inflateEnd(strm) 1305221b1638SMasahiro Yamada z_streamp strm; 1306221b1638SMasahiro Yamada { 1307221b1638SMasahiro Yamada struct inflate_state FAR *state; 1308221b1638SMasahiro Yamada if (inflateStateCheck(strm)) 1309221b1638SMasahiro Yamada return Z_STREAM_ERROR; 1310221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1311221b1638SMasahiro Yamada if (state->window != Z_NULL) ZFREE(strm, state->window); 1312221b1638SMasahiro Yamada ZFREE(strm, strm->state); 1313221b1638SMasahiro Yamada strm->state = Z_NULL; 1314221b1638SMasahiro Yamada Tracev((stderr, "inflate: end\n")); 1315221b1638SMasahiro Yamada return Z_OK; 1316221b1638SMasahiro Yamada } 1317221b1638SMasahiro Yamada 1318221b1638SMasahiro Yamada int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) 1319221b1638SMasahiro Yamada z_streamp strm; 1320221b1638SMasahiro Yamada Bytef *dictionary; 1321221b1638SMasahiro Yamada uInt *dictLength; 1322221b1638SMasahiro Yamada { 1323221b1638SMasahiro Yamada struct inflate_state FAR *state; 1324221b1638SMasahiro Yamada 1325221b1638SMasahiro Yamada /* check state */ 1326221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1327221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1328221b1638SMasahiro Yamada 1329221b1638SMasahiro Yamada /* copy dictionary */ 1330221b1638SMasahiro Yamada if (state->whave && dictionary != Z_NULL) { 1331221b1638SMasahiro Yamada zmemcpy(dictionary, state->window + state->wnext, 1332221b1638SMasahiro Yamada state->whave - state->wnext); 1333221b1638SMasahiro Yamada zmemcpy(dictionary + state->whave - state->wnext, 1334221b1638SMasahiro Yamada state->window, state->wnext); 1335221b1638SMasahiro Yamada } 1336221b1638SMasahiro Yamada if (dictLength != Z_NULL) 1337221b1638SMasahiro Yamada *dictLength = state->whave; 1338221b1638SMasahiro Yamada return Z_OK; 1339221b1638SMasahiro Yamada } 1340221b1638SMasahiro Yamada 1341221b1638SMasahiro Yamada int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) 1342221b1638SMasahiro Yamada z_streamp strm; 1343221b1638SMasahiro Yamada const Bytef *dictionary; 1344221b1638SMasahiro Yamada uInt dictLength; 1345221b1638SMasahiro Yamada { 1346221b1638SMasahiro Yamada struct inflate_state FAR *state; 1347221b1638SMasahiro Yamada unsigned long dictid; 1348221b1638SMasahiro Yamada int ret; 1349221b1638SMasahiro Yamada 1350221b1638SMasahiro Yamada /* check state */ 1351221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1352221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1353221b1638SMasahiro Yamada if (state->wrap != 0 && state->mode != DICT) 1354221b1638SMasahiro Yamada return Z_STREAM_ERROR; 1355221b1638SMasahiro Yamada 1356221b1638SMasahiro Yamada /* check for correct dictionary identifier */ 1357221b1638SMasahiro Yamada if (state->mode == DICT) { 1358221b1638SMasahiro Yamada dictid = adler32(0L, Z_NULL, 0); 1359221b1638SMasahiro Yamada dictid = adler32(dictid, dictionary, dictLength); 1360221b1638SMasahiro Yamada if (dictid != state->check) 1361221b1638SMasahiro Yamada return Z_DATA_ERROR; 1362221b1638SMasahiro Yamada } 1363221b1638SMasahiro Yamada 1364221b1638SMasahiro Yamada /* copy dictionary to window using updatewindow(), which will amend the 1365221b1638SMasahiro Yamada existing dictionary if appropriate */ 1366221b1638SMasahiro Yamada ret = updatewindow(strm, dictionary + dictLength, dictLength); 1367221b1638SMasahiro Yamada if (ret) { 1368221b1638SMasahiro Yamada state->mode = MEM; 1369221b1638SMasahiro Yamada return Z_MEM_ERROR; 1370221b1638SMasahiro Yamada } 1371221b1638SMasahiro Yamada state->havedict = 1; 1372221b1638SMasahiro Yamada Tracev((stderr, "inflate: dictionary set\n")); 1373221b1638SMasahiro Yamada return Z_OK; 1374221b1638SMasahiro Yamada } 1375221b1638SMasahiro Yamada 1376221b1638SMasahiro Yamada int ZEXPORT inflateGetHeader(strm, head) 1377221b1638SMasahiro Yamada z_streamp strm; 1378221b1638SMasahiro Yamada gz_headerp head; 1379221b1638SMasahiro Yamada { 1380221b1638SMasahiro Yamada struct inflate_state FAR *state; 1381221b1638SMasahiro Yamada 1382221b1638SMasahiro Yamada /* check state */ 1383221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1384221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1385221b1638SMasahiro Yamada if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; 1386221b1638SMasahiro Yamada 1387221b1638SMasahiro Yamada /* save header structure */ 1388221b1638SMasahiro Yamada state->head = head; 1389221b1638SMasahiro Yamada head->done = 0; 1390221b1638SMasahiro Yamada return Z_OK; 1391221b1638SMasahiro Yamada } 1392221b1638SMasahiro Yamada 1393221b1638SMasahiro Yamada /* 1394221b1638SMasahiro Yamada Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found 1395221b1638SMasahiro Yamada or when out of input. When called, *have is the number of pattern bytes 1396221b1638SMasahiro Yamada found in order so far, in 0..3. On return *have is updated to the new 1397221b1638SMasahiro Yamada state. If on return *have equals four, then the pattern was found and the 1398221b1638SMasahiro Yamada return value is how many bytes were read including the last byte of the 1399221b1638SMasahiro Yamada pattern. If *have is less than four, then the pattern has not been found 1400221b1638SMasahiro Yamada yet and the return value is len. In the latter case, syncsearch() can be 1401221b1638SMasahiro Yamada called again with more data and the *have state. *have is initialized to 1402221b1638SMasahiro Yamada zero for the first call. 1403221b1638SMasahiro Yamada */ 1404221b1638SMasahiro Yamada local unsigned syncsearch(have, buf, len) 1405221b1638SMasahiro Yamada unsigned FAR *have; 1406221b1638SMasahiro Yamada const unsigned char FAR *buf; 1407221b1638SMasahiro Yamada unsigned len; 1408221b1638SMasahiro Yamada { 1409221b1638SMasahiro Yamada unsigned got; 1410221b1638SMasahiro Yamada unsigned next; 1411221b1638SMasahiro Yamada 1412221b1638SMasahiro Yamada got = *have; 1413221b1638SMasahiro Yamada next = 0; 1414221b1638SMasahiro Yamada while (next < len && got < 4) { 1415221b1638SMasahiro Yamada if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) 1416221b1638SMasahiro Yamada got++; 1417221b1638SMasahiro Yamada else if (buf[next]) 1418221b1638SMasahiro Yamada got = 0; 1419221b1638SMasahiro Yamada else 1420221b1638SMasahiro Yamada got = 4 - got; 1421221b1638SMasahiro Yamada next++; 1422221b1638SMasahiro Yamada } 1423221b1638SMasahiro Yamada *have = got; 1424221b1638SMasahiro Yamada return next; 1425221b1638SMasahiro Yamada } 1426221b1638SMasahiro Yamada 1427221b1638SMasahiro Yamada int ZEXPORT inflateSync(strm) 1428221b1638SMasahiro Yamada z_streamp strm; 1429221b1638SMasahiro Yamada { 1430221b1638SMasahiro Yamada unsigned len; /* number of bytes to look at or looked at */ 1431*a194255dSDaniel Boulby int flags; /* temporary to save header status */ 1432221b1638SMasahiro Yamada unsigned long in, out; /* temporary to save total_in and total_out */ 1433221b1638SMasahiro Yamada unsigned char buf[4]; /* to restore bit buffer to byte string */ 1434221b1638SMasahiro Yamada struct inflate_state FAR *state; 1435221b1638SMasahiro Yamada 1436221b1638SMasahiro Yamada /* check parameters */ 1437221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1438221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1439221b1638SMasahiro Yamada if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; 1440221b1638SMasahiro Yamada 1441221b1638SMasahiro Yamada /* if first time, start search in bit buffer */ 1442221b1638SMasahiro Yamada if (state->mode != SYNC) { 1443221b1638SMasahiro Yamada state->mode = SYNC; 1444221b1638SMasahiro Yamada state->hold <<= state->bits & 7; 1445221b1638SMasahiro Yamada state->bits -= state->bits & 7; 1446221b1638SMasahiro Yamada len = 0; 1447221b1638SMasahiro Yamada while (state->bits >= 8) { 1448221b1638SMasahiro Yamada buf[len++] = (unsigned char)(state->hold); 1449221b1638SMasahiro Yamada state->hold >>= 8; 1450221b1638SMasahiro Yamada state->bits -= 8; 1451221b1638SMasahiro Yamada } 1452221b1638SMasahiro Yamada state->have = 0; 1453221b1638SMasahiro Yamada syncsearch(&(state->have), buf, len); 1454221b1638SMasahiro Yamada } 1455221b1638SMasahiro Yamada 1456221b1638SMasahiro Yamada /* search available input */ 1457221b1638SMasahiro Yamada len = syncsearch(&(state->have), strm->next_in, strm->avail_in); 1458221b1638SMasahiro Yamada strm->avail_in -= len; 1459221b1638SMasahiro Yamada strm->next_in += len; 1460221b1638SMasahiro Yamada strm->total_in += len; 1461221b1638SMasahiro Yamada 1462221b1638SMasahiro Yamada /* return no joy or set up to restart inflate() on a new block */ 1463221b1638SMasahiro Yamada if (state->have != 4) return Z_DATA_ERROR; 1464*a194255dSDaniel Boulby if (state->flags == -1) 1465*a194255dSDaniel Boulby state->wrap = 0; /* if no header yet, treat as raw */ 1466*a194255dSDaniel Boulby else 1467*a194255dSDaniel Boulby state->wrap &= ~4; /* no point in computing a check value now */ 1468*a194255dSDaniel Boulby flags = state->flags; 1469221b1638SMasahiro Yamada in = strm->total_in; out = strm->total_out; 1470221b1638SMasahiro Yamada inflateReset(strm); 1471221b1638SMasahiro Yamada strm->total_in = in; strm->total_out = out; 1472*a194255dSDaniel Boulby state->flags = flags; 1473221b1638SMasahiro Yamada state->mode = TYPE; 1474221b1638SMasahiro Yamada return Z_OK; 1475221b1638SMasahiro Yamada } 1476221b1638SMasahiro Yamada 1477221b1638SMasahiro Yamada /* 1478221b1638SMasahiro Yamada Returns true if inflate is currently at the end of a block generated by 1479221b1638SMasahiro Yamada Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP 1480221b1638SMasahiro Yamada implementation to provide an additional safety check. PPP uses 1481221b1638SMasahiro Yamada Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored 1482221b1638SMasahiro Yamada block. When decompressing, PPP checks that at the end of input packet, 1483221b1638SMasahiro Yamada inflate is waiting for these length bytes. 1484221b1638SMasahiro Yamada */ 1485221b1638SMasahiro Yamada int ZEXPORT inflateSyncPoint(strm) 1486221b1638SMasahiro Yamada z_streamp strm; 1487221b1638SMasahiro Yamada { 1488221b1638SMasahiro Yamada struct inflate_state FAR *state; 1489221b1638SMasahiro Yamada 1490221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1491221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1492221b1638SMasahiro Yamada return state->mode == STORED && state->bits == 0; 1493221b1638SMasahiro Yamada } 1494221b1638SMasahiro Yamada 1495221b1638SMasahiro Yamada int ZEXPORT inflateCopy(dest, source) 1496221b1638SMasahiro Yamada z_streamp dest; 1497221b1638SMasahiro Yamada z_streamp source; 1498221b1638SMasahiro Yamada { 1499221b1638SMasahiro Yamada struct inflate_state FAR *state; 1500221b1638SMasahiro Yamada struct inflate_state FAR *copy; 1501221b1638SMasahiro Yamada unsigned char FAR *window; 1502221b1638SMasahiro Yamada unsigned wsize; 1503221b1638SMasahiro Yamada 1504221b1638SMasahiro Yamada /* check input */ 1505221b1638SMasahiro Yamada if (inflateStateCheck(source) || dest == Z_NULL) 1506221b1638SMasahiro Yamada return Z_STREAM_ERROR; 1507221b1638SMasahiro Yamada state = (struct inflate_state FAR *)source->state; 1508221b1638SMasahiro Yamada 1509221b1638SMasahiro Yamada /* allocate space */ 1510221b1638SMasahiro Yamada copy = (struct inflate_state FAR *) 1511221b1638SMasahiro Yamada ZALLOC(source, 1, sizeof(struct inflate_state)); 1512221b1638SMasahiro Yamada if (copy == Z_NULL) return Z_MEM_ERROR; 1513221b1638SMasahiro Yamada window = Z_NULL; 1514221b1638SMasahiro Yamada if (state->window != Z_NULL) { 1515221b1638SMasahiro Yamada window = (unsigned char FAR *) 1516221b1638SMasahiro Yamada ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); 1517221b1638SMasahiro Yamada if (window == Z_NULL) { 1518221b1638SMasahiro Yamada ZFREE(source, copy); 1519221b1638SMasahiro Yamada return Z_MEM_ERROR; 1520221b1638SMasahiro Yamada } 1521221b1638SMasahiro Yamada } 1522221b1638SMasahiro Yamada 1523221b1638SMasahiro Yamada /* copy state */ 1524221b1638SMasahiro Yamada zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); 1525221b1638SMasahiro Yamada zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); 1526221b1638SMasahiro Yamada copy->strm = dest; 1527221b1638SMasahiro Yamada if (state->lencode >= state->codes && 1528221b1638SMasahiro Yamada state->lencode <= state->codes + ENOUGH - 1) { 1529221b1638SMasahiro Yamada copy->lencode = copy->codes + (state->lencode - state->codes); 1530221b1638SMasahiro Yamada copy->distcode = copy->codes + (state->distcode - state->codes); 1531221b1638SMasahiro Yamada } 1532221b1638SMasahiro Yamada copy->next = copy->codes + (state->next - state->codes); 1533221b1638SMasahiro Yamada if (window != Z_NULL) { 1534221b1638SMasahiro Yamada wsize = 1U << state->wbits; 1535221b1638SMasahiro Yamada zmemcpy(window, state->window, wsize); 1536221b1638SMasahiro Yamada } 1537221b1638SMasahiro Yamada copy->window = window; 1538221b1638SMasahiro Yamada dest->state = (struct internal_state FAR *)copy; 1539221b1638SMasahiro Yamada return Z_OK; 1540221b1638SMasahiro Yamada } 1541221b1638SMasahiro Yamada 1542221b1638SMasahiro Yamada int ZEXPORT inflateUndermine(strm, subvert) 1543221b1638SMasahiro Yamada z_streamp strm; 1544221b1638SMasahiro Yamada int subvert; 1545221b1638SMasahiro Yamada { 1546221b1638SMasahiro Yamada struct inflate_state FAR *state; 1547221b1638SMasahiro Yamada 1548221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1549221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1550221b1638SMasahiro Yamada #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 1551221b1638SMasahiro Yamada state->sane = !subvert; 1552221b1638SMasahiro Yamada return Z_OK; 1553221b1638SMasahiro Yamada #else 1554221b1638SMasahiro Yamada (void)subvert; 1555221b1638SMasahiro Yamada state->sane = 1; 1556221b1638SMasahiro Yamada return Z_DATA_ERROR; 1557221b1638SMasahiro Yamada #endif 1558221b1638SMasahiro Yamada } 1559221b1638SMasahiro Yamada 1560221b1638SMasahiro Yamada int ZEXPORT inflateValidate(strm, check) 1561221b1638SMasahiro Yamada z_streamp strm; 1562221b1638SMasahiro Yamada int check; 1563221b1638SMasahiro Yamada { 1564221b1638SMasahiro Yamada struct inflate_state FAR *state; 1565221b1638SMasahiro Yamada 1566221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1567221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1568*a194255dSDaniel Boulby if (check && state->wrap) 1569221b1638SMasahiro Yamada state->wrap |= 4; 1570221b1638SMasahiro Yamada else 1571221b1638SMasahiro Yamada state->wrap &= ~4; 1572221b1638SMasahiro Yamada return Z_OK; 1573221b1638SMasahiro Yamada } 1574221b1638SMasahiro Yamada 1575221b1638SMasahiro Yamada long ZEXPORT inflateMark(strm) 1576221b1638SMasahiro Yamada z_streamp strm; 1577221b1638SMasahiro Yamada { 1578221b1638SMasahiro Yamada struct inflate_state FAR *state; 1579221b1638SMasahiro Yamada 1580221b1638SMasahiro Yamada if (inflateStateCheck(strm)) 1581221b1638SMasahiro Yamada return -(1L << 16); 1582221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1583221b1638SMasahiro Yamada return (long)(((unsigned long)((long)state->back)) << 16) + 1584221b1638SMasahiro Yamada (state->mode == COPY ? state->length : 1585221b1638SMasahiro Yamada (state->mode == MATCH ? state->was - state->length : 0)); 1586221b1638SMasahiro Yamada } 1587221b1638SMasahiro Yamada 1588221b1638SMasahiro Yamada unsigned long ZEXPORT inflateCodesUsed(strm) 1589221b1638SMasahiro Yamada z_streamp strm; 1590221b1638SMasahiro Yamada { 1591221b1638SMasahiro Yamada struct inflate_state FAR *state; 1592221b1638SMasahiro Yamada if (inflateStateCheck(strm)) return (unsigned long)-1; 1593221b1638SMasahiro Yamada state = (struct inflate_state FAR *)strm->state; 1594221b1638SMasahiro Yamada return (unsigned long)(state->next - state->codes); 1595221b1638SMasahiro Yamada } 1596