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