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