11cb0ef41Sopenharmony_ci/* inflate.c -- zlib decompression 21cb0ef41Sopenharmony_ci * Copyright (C) 1995-2022 Mark Adler 31cb0ef41Sopenharmony_ci * For conditions of distribution and use, see copyright notice in zlib.h 41cb0ef41Sopenharmony_ci */ 51cb0ef41Sopenharmony_ci 61cb0ef41Sopenharmony_ci/* 71cb0ef41Sopenharmony_ci * Change history: 81cb0ef41Sopenharmony_ci * 91cb0ef41Sopenharmony_ci * 1.2.beta0 24 Nov 2002 101cb0ef41Sopenharmony_ci * - First version -- complete rewrite of inflate to simplify code, avoid 111cb0ef41Sopenharmony_ci * creation of window when not needed, minimize use of window when it is 121cb0ef41Sopenharmony_ci * needed, make inffast.c even faster, implement gzip decoding, and to 131cb0ef41Sopenharmony_ci * improve code readability and style over the previous zlib inflate code 141cb0ef41Sopenharmony_ci * 151cb0ef41Sopenharmony_ci * 1.2.beta1 25 Nov 2002 161cb0ef41Sopenharmony_ci * - Use pointers for available input and output checking in inffast.c 171cb0ef41Sopenharmony_ci * - Remove input and output counters in inffast.c 181cb0ef41Sopenharmony_ci * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 191cb0ef41Sopenharmony_ci * - Remove unnecessary second byte pull from length extra in inffast.c 201cb0ef41Sopenharmony_ci * - Unroll direct copy to three copies per loop in inffast.c 211cb0ef41Sopenharmony_ci * 221cb0ef41Sopenharmony_ci * 1.2.beta2 4 Dec 2002 231cb0ef41Sopenharmony_ci * - Change external routine names to reduce potential conflicts 241cb0ef41Sopenharmony_ci * - Correct filename to inffixed.h for fixed tables in inflate.c 251cb0ef41Sopenharmony_ci * - Make hbuf[] unsigned char to match parameter type in inflate.c 261cb0ef41Sopenharmony_ci * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) 271cb0ef41Sopenharmony_ci * to avoid negation problem on Alphas (64 bit) in inflate.c 281cb0ef41Sopenharmony_ci * 291cb0ef41Sopenharmony_ci * 1.2.beta3 22 Dec 2002 301cb0ef41Sopenharmony_ci * - Add comments on state->bits assertion in inffast.c 311cb0ef41Sopenharmony_ci * - Add comments on op field in inftrees.h 321cb0ef41Sopenharmony_ci * - Fix bug in reuse of allocated window after inflateReset() 331cb0ef41Sopenharmony_ci * - Remove bit fields--back to byte structure for speed 341cb0ef41Sopenharmony_ci * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths 351cb0ef41Sopenharmony_ci * - Change post-increments to pre-increments in inflate_fast(), PPC biased? 361cb0ef41Sopenharmony_ci * - Add compile time option, POSTINC, to use post-increments instead (Intel?) 371cb0ef41Sopenharmony_ci * - Make MATCH copy in inflate() much faster for when inflate_fast() not used 381cb0ef41Sopenharmony_ci * - Use local copies of stream next and avail values, as well as local bit 391cb0ef41Sopenharmony_ci * buffer and bit count in inflate()--for speed when inflate_fast() not used 401cb0ef41Sopenharmony_ci * 411cb0ef41Sopenharmony_ci * 1.2.beta4 1 Jan 2003 421cb0ef41Sopenharmony_ci * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings 431cb0ef41Sopenharmony_ci * - Move a comment on output buffer sizes from inffast.c to inflate.c 441cb0ef41Sopenharmony_ci * - Add comments in inffast.c to introduce the inflate_fast() routine 451cb0ef41Sopenharmony_ci * - Rearrange window copies in inflate_fast() for speed and simplification 461cb0ef41Sopenharmony_ci * - Unroll last copy for window match in inflate_fast() 471cb0ef41Sopenharmony_ci * - Use local copies of window variables in inflate_fast() for speed 481cb0ef41Sopenharmony_ci * - Pull out common wnext == 0 case for speed in inflate_fast() 491cb0ef41Sopenharmony_ci * - Make op and len in inflate_fast() unsigned for consistency 501cb0ef41Sopenharmony_ci * - Add FAR to lcode and dcode declarations in inflate_fast() 511cb0ef41Sopenharmony_ci * - Simplified bad distance check in inflate_fast() 521cb0ef41Sopenharmony_ci * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new 531cb0ef41Sopenharmony_ci * source file infback.c to provide a call-back interface to inflate for 541cb0ef41Sopenharmony_ci * programs like gzip and unzip -- uses window as output buffer to avoid 551cb0ef41Sopenharmony_ci * window copying 561cb0ef41Sopenharmony_ci * 571cb0ef41Sopenharmony_ci * 1.2.beta5 1 Jan 2003 581cb0ef41Sopenharmony_ci * - Improved inflateBack() interface to allow the caller to provide initial 591cb0ef41Sopenharmony_ci * input in strm. 601cb0ef41Sopenharmony_ci * - Fixed stored blocks bug in inflateBack() 611cb0ef41Sopenharmony_ci * 621cb0ef41Sopenharmony_ci * 1.2.beta6 4 Jan 2003 631cb0ef41Sopenharmony_ci * - Added comments in inffast.c on effectiveness of POSTINC 641cb0ef41Sopenharmony_ci * - Typecasting all around to reduce compiler warnings 651cb0ef41Sopenharmony_ci * - Changed loops from while (1) or do {} while (1) to for (;;), again to 661cb0ef41Sopenharmony_ci * make compilers happy 671cb0ef41Sopenharmony_ci * - Changed type of window in inflateBackInit() to unsigned char * 681cb0ef41Sopenharmony_ci * 691cb0ef41Sopenharmony_ci * 1.2.beta7 27 Jan 2003 701cb0ef41Sopenharmony_ci * - Changed many types to unsigned or unsigned short to avoid warnings 711cb0ef41Sopenharmony_ci * - Added inflateCopy() function 721cb0ef41Sopenharmony_ci * 731cb0ef41Sopenharmony_ci * 1.2.0 9 Mar 2003 741cb0ef41Sopenharmony_ci * - Changed inflateBack() interface to provide separate opaque descriptors 751cb0ef41Sopenharmony_ci * for the in() and out() functions 761cb0ef41Sopenharmony_ci * - Changed inflateBack() argument and in_func typedef to swap the length 771cb0ef41Sopenharmony_ci * and buffer address return values for the input function 781cb0ef41Sopenharmony_ci * - Check next_in and next_out for Z_NULL on entry to inflate() 791cb0ef41Sopenharmony_ci * 801cb0ef41Sopenharmony_ci * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. 811cb0ef41Sopenharmony_ci */ 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci#include "zutil.h" 841cb0ef41Sopenharmony_ci#include "inftrees.h" 851cb0ef41Sopenharmony_ci#include "inflate.h" 861cb0ef41Sopenharmony_ci#include "contrib/optimizations/inffast_chunk.h" 871cb0ef41Sopenharmony_ci#include "contrib/optimizations/chunkcopy.h" 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ci#ifdef MAKEFIXED 901cb0ef41Sopenharmony_ci# ifndef BUILDFIXED 911cb0ef41Sopenharmony_ci# define BUILDFIXED 921cb0ef41Sopenharmony_ci# endif 931cb0ef41Sopenharmony_ci#endif 941cb0ef41Sopenharmony_ci 951cb0ef41Sopenharmony_cilocal int inflateStateCheck(z_streamp strm) { 961cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 971cb0ef41Sopenharmony_ci if (strm == Z_NULL || 981cb0ef41Sopenharmony_ci strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) 991cb0ef41Sopenharmony_ci return 1; 1001cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 1011cb0ef41Sopenharmony_ci if (state == Z_NULL || state->strm != strm || 1021cb0ef41Sopenharmony_ci state->mode < HEAD || state->mode > SYNC) 1031cb0ef41Sopenharmony_ci return 1; 1041cb0ef41Sopenharmony_ci return 0; 1051cb0ef41Sopenharmony_ci} 1061cb0ef41Sopenharmony_ci 1071cb0ef41Sopenharmony_ciint ZEXPORT inflateResetKeep(z_streamp strm) { 1081cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 1091cb0ef41Sopenharmony_ci 1101cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1111cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 1121cb0ef41Sopenharmony_ci strm->total_in = strm->total_out = state->total = 0; 1131cb0ef41Sopenharmony_ci strm->msg = Z_NULL; 1141cb0ef41Sopenharmony_ci if (state->wrap) /* to support ill-conceived Java test suite */ 1151cb0ef41Sopenharmony_ci strm->adler = state->wrap & 1; 1161cb0ef41Sopenharmony_ci state->mode = HEAD; 1171cb0ef41Sopenharmony_ci state->last = 0; 1181cb0ef41Sopenharmony_ci state->havedict = 0; 1191cb0ef41Sopenharmony_ci state->flags = -1; 1201cb0ef41Sopenharmony_ci state->dmax = 32768U; 1211cb0ef41Sopenharmony_ci state->head = Z_NULL; 1221cb0ef41Sopenharmony_ci state->hold = 0; 1231cb0ef41Sopenharmony_ci state->bits = 0; 1241cb0ef41Sopenharmony_ci state->lencode = state->distcode = state->next = state->codes; 1251cb0ef41Sopenharmony_ci state->sane = 1; 1261cb0ef41Sopenharmony_ci state->back = -1; 1271cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: reset\n")); 1281cb0ef41Sopenharmony_ci return Z_OK; 1291cb0ef41Sopenharmony_ci} 1301cb0ef41Sopenharmony_ci 1311cb0ef41Sopenharmony_ciint ZEXPORT inflateReset(z_streamp strm) { 1321cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 1331cb0ef41Sopenharmony_ci 1341cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1351cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 1361cb0ef41Sopenharmony_ci state->wsize = 0; 1371cb0ef41Sopenharmony_ci state->whave = 0; 1381cb0ef41Sopenharmony_ci state->wnext = 0; 1391cb0ef41Sopenharmony_ci return inflateResetKeep(strm); 1401cb0ef41Sopenharmony_ci} 1411cb0ef41Sopenharmony_ci 1421cb0ef41Sopenharmony_ciint ZEXPORT inflateReset2(z_streamp strm, int windowBits) { 1431cb0ef41Sopenharmony_ci int wrap; 1441cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 1451cb0ef41Sopenharmony_ci 1461cb0ef41Sopenharmony_ci /* get the state */ 1471cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 1481cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 1491cb0ef41Sopenharmony_ci 1501cb0ef41Sopenharmony_ci /* extract wrap request from windowBits parameter */ 1511cb0ef41Sopenharmony_ci if (windowBits < 0) { 1521cb0ef41Sopenharmony_ci if (windowBits < -15) 1531cb0ef41Sopenharmony_ci return Z_STREAM_ERROR; 1541cb0ef41Sopenharmony_ci wrap = 0; 1551cb0ef41Sopenharmony_ci windowBits = -windowBits; 1561cb0ef41Sopenharmony_ci } 1571cb0ef41Sopenharmony_ci else { 1581cb0ef41Sopenharmony_ci wrap = (windowBits >> 4) + 5; 1591cb0ef41Sopenharmony_ci#ifdef GUNZIP 1601cb0ef41Sopenharmony_ci if (windowBits < 48) 1611cb0ef41Sopenharmony_ci windowBits &= 15; 1621cb0ef41Sopenharmony_ci#endif 1631cb0ef41Sopenharmony_ci } 1641cb0ef41Sopenharmony_ci 1651cb0ef41Sopenharmony_ci /* set number of window bits, free window if different */ 1661cb0ef41Sopenharmony_ci if (windowBits && (windowBits < 8 || windowBits > 15)) 1671cb0ef41Sopenharmony_ci return Z_STREAM_ERROR; 1681cb0ef41Sopenharmony_ci if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { 1691cb0ef41Sopenharmony_ci ZFREE(strm, state->window); 1701cb0ef41Sopenharmony_ci state->window = Z_NULL; 1711cb0ef41Sopenharmony_ci } 1721cb0ef41Sopenharmony_ci 1731cb0ef41Sopenharmony_ci /* update state and reset the rest of it */ 1741cb0ef41Sopenharmony_ci state->wrap = wrap; 1751cb0ef41Sopenharmony_ci state->wbits = (unsigned)windowBits; 1761cb0ef41Sopenharmony_ci return inflateReset(strm); 1771cb0ef41Sopenharmony_ci} 1781cb0ef41Sopenharmony_ci 1791cb0ef41Sopenharmony_ciint ZEXPORT inflateInit2_(z_streamp strm, int windowBits, 1801cb0ef41Sopenharmony_ci const char *version, int stream_size) { 1811cb0ef41Sopenharmony_ci int ret; 1821cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ci if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 1851cb0ef41Sopenharmony_ci stream_size != (int)(sizeof(z_stream))) 1861cb0ef41Sopenharmony_ci return Z_VERSION_ERROR; 1871cb0ef41Sopenharmony_ci if (strm == Z_NULL) return Z_STREAM_ERROR; 1881cb0ef41Sopenharmony_ci strm->msg = Z_NULL; /* in case we return an error */ 1891cb0ef41Sopenharmony_ci if (strm->zalloc == (alloc_func)0) { 1901cb0ef41Sopenharmony_ci#ifdef Z_SOLO 1911cb0ef41Sopenharmony_ci return Z_STREAM_ERROR; 1921cb0ef41Sopenharmony_ci#else 1931cb0ef41Sopenharmony_ci strm->zalloc = zcalloc; 1941cb0ef41Sopenharmony_ci strm->opaque = (voidpf)0; 1951cb0ef41Sopenharmony_ci#endif 1961cb0ef41Sopenharmony_ci } 1971cb0ef41Sopenharmony_ci if (strm->zfree == (free_func)0) 1981cb0ef41Sopenharmony_ci#ifdef Z_SOLO 1991cb0ef41Sopenharmony_ci return Z_STREAM_ERROR; 2001cb0ef41Sopenharmony_ci#else 2011cb0ef41Sopenharmony_ci strm->zfree = zcfree; 2021cb0ef41Sopenharmony_ci#endif 2031cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *) 2041cb0ef41Sopenharmony_ci ZALLOC(strm, 1, sizeof(struct inflate_state)); 2051cb0ef41Sopenharmony_ci if (state == Z_NULL) return Z_MEM_ERROR; 2061cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: allocated\n")); 2071cb0ef41Sopenharmony_ci strm->state = (struct internal_state FAR *)state; 2081cb0ef41Sopenharmony_ci state->strm = strm; 2091cb0ef41Sopenharmony_ci state->window = Z_NULL; 2101cb0ef41Sopenharmony_ci state->mode = HEAD; /* to pass state test in inflateReset2() */ 2111cb0ef41Sopenharmony_ci state->check = 1L; /* 1L is the result of adler32() zero length data */ 2121cb0ef41Sopenharmony_ci ret = inflateReset2(strm, windowBits); 2131cb0ef41Sopenharmony_ci if (ret != Z_OK) { 2141cb0ef41Sopenharmony_ci ZFREE(strm, state); 2151cb0ef41Sopenharmony_ci strm->state = Z_NULL; 2161cb0ef41Sopenharmony_ci } 2171cb0ef41Sopenharmony_ci return ret; 2181cb0ef41Sopenharmony_ci} 2191cb0ef41Sopenharmony_ci 2201cb0ef41Sopenharmony_ciint ZEXPORT inflateInit_(z_streamp strm, const char *version, 2211cb0ef41Sopenharmony_ci int stream_size) { 2221cb0ef41Sopenharmony_ci return inflateInit2_(strm, DEF_WBITS, version, stream_size); 2231cb0ef41Sopenharmony_ci} 2241cb0ef41Sopenharmony_ci 2251cb0ef41Sopenharmony_ciint ZEXPORT inflatePrime(z_streamp strm, int bits, int value) { 2261cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 2271cb0ef41Sopenharmony_ci 2281cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 2291cb0ef41Sopenharmony_ci if (bits == 0) 2301cb0ef41Sopenharmony_ci return Z_OK; 2311cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 2321cb0ef41Sopenharmony_ci if (bits < 0) { 2331cb0ef41Sopenharmony_ci state->hold = 0; 2341cb0ef41Sopenharmony_ci state->bits = 0; 2351cb0ef41Sopenharmony_ci return Z_OK; 2361cb0ef41Sopenharmony_ci } 2371cb0ef41Sopenharmony_ci if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR; 2381cb0ef41Sopenharmony_ci value &= (1L << bits) - 1; 2391cb0ef41Sopenharmony_ci state->hold += (unsigned)value << state->bits; 2401cb0ef41Sopenharmony_ci state->bits += (uInt)bits; 2411cb0ef41Sopenharmony_ci return Z_OK; 2421cb0ef41Sopenharmony_ci} 2431cb0ef41Sopenharmony_ci 2441cb0ef41Sopenharmony_ci/* 2451cb0ef41Sopenharmony_ci Return state with length and distance decoding tables and index sizes set to 2461cb0ef41Sopenharmony_ci fixed code decoding. Normally this returns fixed tables from inffixed.h. 2471cb0ef41Sopenharmony_ci If BUILDFIXED is defined, then instead this routine builds the tables the 2481cb0ef41Sopenharmony_ci first time it's called, and returns those tables the first time and 2491cb0ef41Sopenharmony_ci thereafter. This reduces the size of the code by about 2K bytes, in 2501cb0ef41Sopenharmony_ci exchange for a little execution time. However, BUILDFIXED should not be 2511cb0ef41Sopenharmony_ci used for threaded applications, since the rewriting of the tables and virgin 2521cb0ef41Sopenharmony_ci may not be thread-safe. 2531cb0ef41Sopenharmony_ci */ 2541cb0ef41Sopenharmony_cilocal void fixedtables(struct inflate_state FAR *state) { 2551cb0ef41Sopenharmony_ci#ifdef BUILDFIXED 2561cb0ef41Sopenharmony_ci static int virgin = 1; 2571cb0ef41Sopenharmony_ci static code *lenfix, *distfix; 2581cb0ef41Sopenharmony_ci static code fixed[544]; 2591cb0ef41Sopenharmony_ci 2601cb0ef41Sopenharmony_ci /* build fixed huffman tables if first call (may not be thread safe) */ 2611cb0ef41Sopenharmony_ci if (virgin) { 2621cb0ef41Sopenharmony_ci unsigned sym, bits; 2631cb0ef41Sopenharmony_ci static code *next; 2641cb0ef41Sopenharmony_ci 2651cb0ef41Sopenharmony_ci /* literal/length table */ 2661cb0ef41Sopenharmony_ci sym = 0; 2671cb0ef41Sopenharmony_ci while (sym < 144) state->lens[sym++] = 8; 2681cb0ef41Sopenharmony_ci while (sym < 256) state->lens[sym++] = 9; 2691cb0ef41Sopenharmony_ci while (sym < 280) state->lens[sym++] = 7; 2701cb0ef41Sopenharmony_ci while (sym < 288) state->lens[sym++] = 8; 2711cb0ef41Sopenharmony_ci next = fixed; 2721cb0ef41Sopenharmony_ci lenfix = next; 2731cb0ef41Sopenharmony_ci bits = 9; 2741cb0ef41Sopenharmony_ci inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); 2751cb0ef41Sopenharmony_ci 2761cb0ef41Sopenharmony_ci /* distance table */ 2771cb0ef41Sopenharmony_ci sym = 0; 2781cb0ef41Sopenharmony_ci while (sym < 32) state->lens[sym++] = 5; 2791cb0ef41Sopenharmony_ci distfix = next; 2801cb0ef41Sopenharmony_ci bits = 5; 2811cb0ef41Sopenharmony_ci inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); 2821cb0ef41Sopenharmony_ci 2831cb0ef41Sopenharmony_ci /* do this just once */ 2841cb0ef41Sopenharmony_ci virgin = 0; 2851cb0ef41Sopenharmony_ci } 2861cb0ef41Sopenharmony_ci#else /* !BUILDFIXED */ 2871cb0ef41Sopenharmony_ci# include "inffixed.h" 2881cb0ef41Sopenharmony_ci#endif /* BUILDFIXED */ 2891cb0ef41Sopenharmony_ci state->lencode = lenfix; 2901cb0ef41Sopenharmony_ci state->lenbits = 9; 2911cb0ef41Sopenharmony_ci state->distcode = distfix; 2921cb0ef41Sopenharmony_ci state->distbits = 5; 2931cb0ef41Sopenharmony_ci} 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ci#ifdef MAKEFIXED 2961cb0ef41Sopenharmony_ci#include <stdio.h> 2971cb0ef41Sopenharmony_ci 2981cb0ef41Sopenharmony_ci/* 2991cb0ef41Sopenharmony_ci Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also 3001cb0ef41Sopenharmony_ci defines BUILDFIXED, so the tables are built on the fly. makefixed() writes 3011cb0ef41Sopenharmony_ci those tables to stdout, which would be piped to inffixed.h. A small program 3021cb0ef41Sopenharmony_ci can simply call makefixed to do this: 3031cb0ef41Sopenharmony_ci 3041cb0ef41Sopenharmony_ci void makefixed(void); 3051cb0ef41Sopenharmony_ci 3061cb0ef41Sopenharmony_ci int main(void) 3071cb0ef41Sopenharmony_ci { 3081cb0ef41Sopenharmony_ci makefixed(); 3091cb0ef41Sopenharmony_ci return 0; 3101cb0ef41Sopenharmony_ci } 3111cb0ef41Sopenharmony_ci 3121cb0ef41Sopenharmony_ci Then that can be linked with zlib built with MAKEFIXED defined and run: 3131cb0ef41Sopenharmony_ci 3141cb0ef41Sopenharmony_ci a.out > inffixed.h 3151cb0ef41Sopenharmony_ci */ 3161cb0ef41Sopenharmony_civoid makefixed(void) 3171cb0ef41Sopenharmony_ci{ 3181cb0ef41Sopenharmony_ci unsigned low, size; 3191cb0ef41Sopenharmony_ci struct inflate_state state; 3201cb0ef41Sopenharmony_ci 3211cb0ef41Sopenharmony_ci fixedtables(&state); 3221cb0ef41Sopenharmony_ci puts(" /* inffixed.h -- table for decoding fixed codes"); 3231cb0ef41Sopenharmony_ci puts(" * Generated automatically by makefixed()."); 3241cb0ef41Sopenharmony_ci puts(" */"); 3251cb0ef41Sopenharmony_ci puts(""); 3261cb0ef41Sopenharmony_ci puts(" /* WARNING: this file should *not* be used by applications."); 3271cb0ef41Sopenharmony_ci puts(" It is part of the implementation of this library and is"); 3281cb0ef41Sopenharmony_ci puts(" subject to change. Applications should only use zlib.h."); 3291cb0ef41Sopenharmony_ci puts(" */"); 3301cb0ef41Sopenharmony_ci puts(""); 3311cb0ef41Sopenharmony_ci size = 1U << 9; 3321cb0ef41Sopenharmony_ci printf(" static const code lenfix[%u] = {", size); 3331cb0ef41Sopenharmony_ci low = 0; 3341cb0ef41Sopenharmony_ci for (;;) { 3351cb0ef41Sopenharmony_ci if ((low % 7) == 0) printf("\n "); 3361cb0ef41Sopenharmony_ci printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, 3371cb0ef41Sopenharmony_ci state.lencode[low].bits, state.lencode[low].val); 3381cb0ef41Sopenharmony_ci if (++low == size) break; 3391cb0ef41Sopenharmony_ci putchar(','); 3401cb0ef41Sopenharmony_ci } 3411cb0ef41Sopenharmony_ci puts("\n };"); 3421cb0ef41Sopenharmony_ci size = 1U << 5; 3431cb0ef41Sopenharmony_ci printf("\n static const code distfix[%u] = {", size); 3441cb0ef41Sopenharmony_ci low = 0; 3451cb0ef41Sopenharmony_ci for (;;) { 3461cb0ef41Sopenharmony_ci if ((low % 6) == 0) printf("\n "); 3471cb0ef41Sopenharmony_ci printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, 3481cb0ef41Sopenharmony_ci state.distcode[low].val); 3491cb0ef41Sopenharmony_ci if (++low == size) break; 3501cb0ef41Sopenharmony_ci putchar(','); 3511cb0ef41Sopenharmony_ci } 3521cb0ef41Sopenharmony_ci puts("\n };"); 3531cb0ef41Sopenharmony_ci} 3541cb0ef41Sopenharmony_ci#endif /* MAKEFIXED */ 3551cb0ef41Sopenharmony_ci 3561cb0ef41Sopenharmony_ci/* 3571cb0ef41Sopenharmony_ci Update the window with the last wsize (normally 32K) bytes written before 3581cb0ef41Sopenharmony_ci returning. If window does not exist yet, create it. This is only called 3591cb0ef41Sopenharmony_ci when a window is already in use, or when output has been written during this 3601cb0ef41Sopenharmony_ci inflate call, but the end of the deflate stream has not been reached yet. 3611cb0ef41Sopenharmony_ci It is also called to create a window for dictionary data when a dictionary 3621cb0ef41Sopenharmony_ci is loaded. 3631cb0ef41Sopenharmony_ci 3641cb0ef41Sopenharmony_ci Providing output buffers larger than 32K to inflate() should provide a speed 3651cb0ef41Sopenharmony_ci advantage, since only the last 32K of output is copied to the sliding window 3661cb0ef41Sopenharmony_ci upon return from inflate(), and since all distances after the first 32K of 3671cb0ef41Sopenharmony_ci output will fall in the output data, making match copies simpler and faster. 3681cb0ef41Sopenharmony_ci The advantage may be dependent on the size of the processor's data caches. 3691cb0ef41Sopenharmony_ci */ 3701cb0ef41Sopenharmony_cilocal int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) { 3711cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 3721cb0ef41Sopenharmony_ci unsigned dist; 3731cb0ef41Sopenharmony_ci 3741cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 3751cb0ef41Sopenharmony_ci 3761cb0ef41Sopenharmony_ci /* if it hasn't been done already, allocate space for the window */ 3771cb0ef41Sopenharmony_ci if (state->window == Z_NULL) { 3781cb0ef41Sopenharmony_ci unsigned wsize = 1U << state->wbits; 3791cb0ef41Sopenharmony_ci state->window = (unsigned char FAR *) 3801cb0ef41Sopenharmony_ci ZALLOC(strm, wsize + CHUNKCOPY_CHUNK_SIZE, 3811cb0ef41Sopenharmony_ci sizeof(unsigned char)); 3821cb0ef41Sopenharmony_ci if (state->window == Z_NULL) return 1; 3831cb0ef41Sopenharmony_ci#ifdef INFLATE_CLEAR_UNUSED_UNDEFINED 3841cb0ef41Sopenharmony_ci /* Copies from the overflow portion of this buffer are undefined and 3851cb0ef41Sopenharmony_ci may cause analysis tools to raise a warning if we don't initialize 3861cb0ef41Sopenharmony_ci it. However, this undefined data overwrites other undefined data 3871cb0ef41Sopenharmony_ci and is subsequently either overwritten or left deliberately 3881cb0ef41Sopenharmony_ci undefined at the end of decode; so there's really no point. 3891cb0ef41Sopenharmony_ci */ 3901cb0ef41Sopenharmony_ci zmemzero(state->window + wsize, CHUNKCOPY_CHUNK_SIZE); 3911cb0ef41Sopenharmony_ci#endif 3921cb0ef41Sopenharmony_ci } 3931cb0ef41Sopenharmony_ci 3941cb0ef41Sopenharmony_ci /* if window not in use yet, initialize */ 3951cb0ef41Sopenharmony_ci if (state->wsize == 0) { 3961cb0ef41Sopenharmony_ci state->wsize = 1U << state->wbits; 3971cb0ef41Sopenharmony_ci state->wnext = 0; 3981cb0ef41Sopenharmony_ci state->whave = 0; 3991cb0ef41Sopenharmony_ci } 4001cb0ef41Sopenharmony_ci 4011cb0ef41Sopenharmony_ci /* copy state->wsize or less output bytes into the circular window */ 4021cb0ef41Sopenharmony_ci if (copy >= state->wsize) { 4031cb0ef41Sopenharmony_ci zmemcpy(state->window, end - state->wsize, state->wsize); 4041cb0ef41Sopenharmony_ci state->wnext = 0; 4051cb0ef41Sopenharmony_ci state->whave = state->wsize; 4061cb0ef41Sopenharmony_ci } 4071cb0ef41Sopenharmony_ci else { 4081cb0ef41Sopenharmony_ci dist = state->wsize - state->wnext; 4091cb0ef41Sopenharmony_ci if (dist > copy) dist = copy; 4101cb0ef41Sopenharmony_ci zmemcpy(state->window + state->wnext, end - copy, dist); 4111cb0ef41Sopenharmony_ci copy -= dist; 4121cb0ef41Sopenharmony_ci if (copy) { 4131cb0ef41Sopenharmony_ci zmemcpy(state->window, end - copy, copy); 4141cb0ef41Sopenharmony_ci state->wnext = copy; 4151cb0ef41Sopenharmony_ci state->whave = state->wsize; 4161cb0ef41Sopenharmony_ci } 4171cb0ef41Sopenharmony_ci else { 4181cb0ef41Sopenharmony_ci state->wnext += dist; 4191cb0ef41Sopenharmony_ci if (state->wnext == state->wsize) state->wnext = 0; 4201cb0ef41Sopenharmony_ci if (state->whave < state->wsize) state->whave += dist; 4211cb0ef41Sopenharmony_ci } 4221cb0ef41Sopenharmony_ci } 4231cb0ef41Sopenharmony_ci return 0; 4241cb0ef41Sopenharmony_ci} 4251cb0ef41Sopenharmony_ci 4261cb0ef41Sopenharmony_ci/* Macros for inflate(): */ 4271cb0ef41Sopenharmony_ci 4281cb0ef41Sopenharmony_ci/* check function to use adler32() for zlib or crc32() for gzip */ 4291cb0ef41Sopenharmony_ci#ifdef GUNZIP 4301cb0ef41Sopenharmony_ci# define UPDATE_CHECK(check, buf, len) \ 4311cb0ef41Sopenharmony_ci (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) 4321cb0ef41Sopenharmony_ci#else 4331cb0ef41Sopenharmony_ci# define UPDATE_CHECK(check, buf, len) adler32(check, buf, len) 4341cb0ef41Sopenharmony_ci#endif 4351cb0ef41Sopenharmony_ci 4361cb0ef41Sopenharmony_ci/* check macros for header crc */ 4371cb0ef41Sopenharmony_ci#ifdef GUNZIP 4381cb0ef41Sopenharmony_ci# define CRC2(check, word) \ 4391cb0ef41Sopenharmony_ci do { \ 4401cb0ef41Sopenharmony_ci hbuf[0] = (unsigned char)(word); \ 4411cb0ef41Sopenharmony_ci hbuf[1] = (unsigned char)((word) >> 8); \ 4421cb0ef41Sopenharmony_ci check = crc32(check, hbuf, 2); \ 4431cb0ef41Sopenharmony_ci } while (0) 4441cb0ef41Sopenharmony_ci 4451cb0ef41Sopenharmony_ci# define CRC4(check, word) \ 4461cb0ef41Sopenharmony_ci do { \ 4471cb0ef41Sopenharmony_ci hbuf[0] = (unsigned char)(word); \ 4481cb0ef41Sopenharmony_ci hbuf[1] = (unsigned char)((word) >> 8); \ 4491cb0ef41Sopenharmony_ci hbuf[2] = (unsigned char)((word) >> 16); \ 4501cb0ef41Sopenharmony_ci hbuf[3] = (unsigned char)((word) >> 24); \ 4511cb0ef41Sopenharmony_ci check = crc32(check, hbuf, 4); \ 4521cb0ef41Sopenharmony_ci } while (0) 4531cb0ef41Sopenharmony_ci#endif 4541cb0ef41Sopenharmony_ci 4551cb0ef41Sopenharmony_ci/* Load registers with state in inflate() for speed */ 4561cb0ef41Sopenharmony_ci#define LOAD() \ 4571cb0ef41Sopenharmony_ci do { \ 4581cb0ef41Sopenharmony_ci put = strm->next_out; \ 4591cb0ef41Sopenharmony_ci left = strm->avail_out; \ 4601cb0ef41Sopenharmony_ci next = strm->next_in; \ 4611cb0ef41Sopenharmony_ci have = strm->avail_in; \ 4621cb0ef41Sopenharmony_ci hold = state->hold; \ 4631cb0ef41Sopenharmony_ci bits = state->bits; \ 4641cb0ef41Sopenharmony_ci } while (0) 4651cb0ef41Sopenharmony_ci 4661cb0ef41Sopenharmony_ci/* Restore state from registers in inflate() */ 4671cb0ef41Sopenharmony_ci#define RESTORE() \ 4681cb0ef41Sopenharmony_ci do { \ 4691cb0ef41Sopenharmony_ci strm->next_out = put; \ 4701cb0ef41Sopenharmony_ci strm->avail_out = left; \ 4711cb0ef41Sopenharmony_ci strm->next_in = next; \ 4721cb0ef41Sopenharmony_ci strm->avail_in = have; \ 4731cb0ef41Sopenharmony_ci state->hold = hold; \ 4741cb0ef41Sopenharmony_ci state->bits = bits; \ 4751cb0ef41Sopenharmony_ci } while (0) 4761cb0ef41Sopenharmony_ci 4771cb0ef41Sopenharmony_ci/* Clear the input bit accumulator */ 4781cb0ef41Sopenharmony_ci#define INITBITS() \ 4791cb0ef41Sopenharmony_ci do { \ 4801cb0ef41Sopenharmony_ci hold = 0; \ 4811cb0ef41Sopenharmony_ci bits = 0; \ 4821cb0ef41Sopenharmony_ci } while (0) 4831cb0ef41Sopenharmony_ci 4841cb0ef41Sopenharmony_ci/* Get a byte of input into the bit accumulator, or return from inflate() 4851cb0ef41Sopenharmony_ci if there is no input available. */ 4861cb0ef41Sopenharmony_ci#define PULLBYTE() \ 4871cb0ef41Sopenharmony_ci do { \ 4881cb0ef41Sopenharmony_ci if (have == 0) goto inf_leave; \ 4891cb0ef41Sopenharmony_ci have--; \ 4901cb0ef41Sopenharmony_ci hold += (unsigned long)(*next++) << bits; \ 4911cb0ef41Sopenharmony_ci bits += 8; \ 4921cb0ef41Sopenharmony_ci } while (0) 4931cb0ef41Sopenharmony_ci 4941cb0ef41Sopenharmony_ci/* Assure that there are at least n bits in the bit accumulator. If there is 4951cb0ef41Sopenharmony_ci not enough available input to do that, then return from inflate(). */ 4961cb0ef41Sopenharmony_ci#define NEEDBITS(n) \ 4971cb0ef41Sopenharmony_ci do { \ 4981cb0ef41Sopenharmony_ci while (bits < (unsigned)(n)) \ 4991cb0ef41Sopenharmony_ci PULLBYTE(); \ 5001cb0ef41Sopenharmony_ci } while (0) 5011cb0ef41Sopenharmony_ci 5021cb0ef41Sopenharmony_ci/* Return the low n bits of the bit accumulator (n < 16) */ 5031cb0ef41Sopenharmony_ci#define BITS(n) \ 5041cb0ef41Sopenharmony_ci ((unsigned)hold & ((1U << (n)) - 1)) 5051cb0ef41Sopenharmony_ci 5061cb0ef41Sopenharmony_ci/* Remove n bits from the bit accumulator */ 5071cb0ef41Sopenharmony_ci#define DROPBITS(n) \ 5081cb0ef41Sopenharmony_ci do { \ 5091cb0ef41Sopenharmony_ci hold >>= (n); \ 5101cb0ef41Sopenharmony_ci bits -= (unsigned)(n); \ 5111cb0ef41Sopenharmony_ci } while (0) 5121cb0ef41Sopenharmony_ci 5131cb0ef41Sopenharmony_ci/* Remove zero to seven bits as needed to go to a byte boundary */ 5141cb0ef41Sopenharmony_ci#define BYTEBITS() \ 5151cb0ef41Sopenharmony_ci do { \ 5161cb0ef41Sopenharmony_ci hold >>= bits & 7; \ 5171cb0ef41Sopenharmony_ci bits -= bits & 7; \ 5181cb0ef41Sopenharmony_ci } while (0) 5191cb0ef41Sopenharmony_ci 5201cb0ef41Sopenharmony_ci/* 5211cb0ef41Sopenharmony_ci inflate() uses a state machine to process as much input data and generate as 5221cb0ef41Sopenharmony_ci much output data as possible before returning. The state machine is 5231cb0ef41Sopenharmony_ci structured roughly as follows: 5241cb0ef41Sopenharmony_ci 5251cb0ef41Sopenharmony_ci for (;;) switch (state) { 5261cb0ef41Sopenharmony_ci ... 5271cb0ef41Sopenharmony_ci case STATEn: 5281cb0ef41Sopenharmony_ci if (not enough input data or output space to make progress) 5291cb0ef41Sopenharmony_ci return; 5301cb0ef41Sopenharmony_ci ... make progress ... 5311cb0ef41Sopenharmony_ci state = STATEm; 5321cb0ef41Sopenharmony_ci break; 5331cb0ef41Sopenharmony_ci ... 5341cb0ef41Sopenharmony_ci } 5351cb0ef41Sopenharmony_ci 5361cb0ef41Sopenharmony_ci so when inflate() is called again, the same case is attempted again, and 5371cb0ef41Sopenharmony_ci if the appropriate resources are provided, the machine proceeds to the 5381cb0ef41Sopenharmony_ci next state. The NEEDBITS() macro is usually the way the state evaluates 5391cb0ef41Sopenharmony_ci whether it can proceed or should return. NEEDBITS() does the return if 5401cb0ef41Sopenharmony_ci the requested bits are not available. The typical use of the BITS macros 5411cb0ef41Sopenharmony_ci is: 5421cb0ef41Sopenharmony_ci 5431cb0ef41Sopenharmony_ci NEEDBITS(n); 5441cb0ef41Sopenharmony_ci ... do something with BITS(n) ... 5451cb0ef41Sopenharmony_ci DROPBITS(n); 5461cb0ef41Sopenharmony_ci 5471cb0ef41Sopenharmony_ci where NEEDBITS(n) either returns from inflate() if there isn't enough 5481cb0ef41Sopenharmony_ci input left to load n bits into the accumulator, or it continues. BITS(n) 5491cb0ef41Sopenharmony_ci gives the low n bits in the accumulator. When done, DROPBITS(n) drops 5501cb0ef41Sopenharmony_ci the low n bits off the accumulator. INITBITS() clears the accumulator 5511cb0ef41Sopenharmony_ci and sets the number of available bits to zero. BYTEBITS() discards just 5521cb0ef41Sopenharmony_ci enough bits to put the accumulator on a byte boundary. After BYTEBITS() 5531cb0ef41Sopenharmony_ci and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. 5541cb0ef41Sopenharmony_ci 5551cb0ef41Sopenharmony_ci NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return 5561cb0ef41Sopenharmony_ci if there is no input available. The decoding of variable length codes uses 5571cb0ef41Sopenharmony_ci PULLBYTE() directly in order to pull just enough bytes to decode the next 5581cb0ef41Sopenharmony_ci code, and no more. 5591cb0ef41Sopenharmony_ci 5601cb0ef41Sopenharmony_ci Some states loop until they get enough input, making sure that enough 5611cb0ef41Sopenharmony_ci state information is maintained to continue the loop where it left off 5621cb0ef41Sopenharmony_ci if NEEDBITS() returns in the loop. For example, want, need, and keep 5631cb0ef41Sopenharmony_ci would all have to actually be part of the saved state in case NEEDBITS() 5641cb0ef41Sopenharmony_ci returns: 5651cb0ef41Sopenharmony_ci 5661cb0ef41Sopenharmony_ci case STATEw: 5671cb0ef41Sopenharmony_ci while (want < need) { 5681cb0ef41Sopenharmony_ci NEEDBITS(n); 5691cb0ef41Sopenharmony_ci keep[want++] = BITS(n); 5701cb0ef41Sopenharmony_ci DROPBITS(n); 5711cb0ef41Sopenharmony_ci } 5721cb0ef41Sopenharmony_ci state = STATEx; 5731cb0ef41Sopenharmony_ci case STATEx: 5741cb0ef41Sopenharmony_ci 5751cb0ef41Sopenharmony_ci As shown above, if the next state is also the next case, then the break 5761cb0ef41Sopenharmony_ci is omitted. 5771cb0ef41Sopenharmony_ci 5781cb0ef41Sopenharmony_ci A state may also return if there is not enough output space available to 5791cb0ef41Sopenharmony_ci complete that state. Those states are copying stored data, writing a 5801cb0ef41Sopenharmony_ci literal byte, and copying a matching string. 5811cb0ef41Sopenharmony_ci 5821cb0ef41Sopenharmony_ci When returning, a "goto inf_leave" is used to update the total counters, 5831cb0ef41Sopenharmony_ci update the check value, and determine whether any progress has been made 5841cb0ef41Sopenharmony_ci during that inflate() call in order to return the proper return code. 5851cb0ef41Sopenharmony_ci Progress is defined as a change in either strm->avail_in or strm->avail_out. 5861cb0ef41Sopenharmony_ci When there is a window, goto inf_leave will update the window with the last 5871cb0ef41Sopenharmony_ci output written. If a goto inf_leave occurs in the middle of decompression 5881cb0ef41Sopenharmony_ci and there is no window currently, goto inf_leave will create one and copy 5891cb0ef41Sopenharmony_ci output to the window for the next call of inflate(). 5901cb0ef41Sopenharmony_ci 5911cb0ef41Sopenharmony_ci In this implementation, the flush parameter of inflate() only affects the 5921cb0ef41Sopenharmony_ci return code (per zlib.h). inflate() always writes as much as possible to 5931cb0ef41Sopenharmony_ci strm->next_out, given the space available and the provided input--the effect 5941cb0ef41Sopenharmony_ci documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers 5951cb0ef41Sopenharmony_ci the allocation of and copying into a sliding window until necessary, which 5961cb0ef41Sopenharmony_ci provides the effect documented in zlib.h for Z_FINISH when the entire input 5971cb0ef41Sopenharmony_ci stream available. So the only thing the flush parameter actually does is: 5981cb0ef41Sopenharmony_ci when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it 5991cb0ef41Sopenharmony_ci will return Z_BUF_ERROR if it has not reached the end of the stream. 6001cb0ef41Sopenharmony_ci */ 6011cb0ef41Sopenharmony_ci 6021cb0ef41Sopenharmony_ciint ZEXPORT inflate(z_streamp strm, int flush) { 6031cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 6041cb0ef41Sopenharmony_ci z_const unsigned char FAR *next; /* next input */ 6051cb0ef41Sopenharmony_ci unsigned char FAR *put; /* next output */ 6061cb0ef41Sopenharmony_ci unsigned have, left; /* available input and output */ 6071cb0ef41Sopenharmony_ci unsigned long hold; /* bit buffer */ 6081cb0ef41Sopenharmony_ci unsigned bits; /* bits in bit buffer */ 6091cb0ef41Sopenharmony_ci unsigned in, out; /* save starting available input and output */ 6101cb0ef41Sopenharmony_ci unsigned copy; /* number of stored or match bytes to copy */ 6111cb0ef41Sopenharmony_ci unsigned char FAR *from; /* where to copy match bytes from */ 6121cb0ef41Sopenharmony_ci code here; /* current decoding table entry */ 6131cb0ef41Sopenharmony_ci code last; /* parent table entry */ 6141cb0ef41Sopenharmony_ci unsigned len; /* length to copy for repeats, bits to drop */ 6151cb0ef41Sopenharmony_ci int ret; /* return code */ 6161cb0ef41Sopenharmony_ci#ifdef GUNZIP 6171cb0ef41Sopenharmony_ci unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ 6181cb0ef41Sopenharmony_ci#endif 6191cb0ef41Sopenharmony_ci static const unsigned short order[19] = /* permutation of code lengths */ 6201cb0ef41Sopenharmony_ci {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 6211cb0ef41Sopenharmony_ci 6221cb0ef41Sopenharmony_ci if (inflateStateCheck(strm) || strm->next_out == Z_NULL || 6231cb0ef41Sopenharmony_ci (strm->next_in == Z_NULL && strm->avail_in != 0)) 6241cb0ef41Sopenharmony_ci return Z_STREAM_ERROR; 6251cb0ef41Sopenharmony_ci 6261cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 6271cb0ef41Sopenharmony_ci if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ 6281cb0ef41Sopenharmony_ci LOAD(); 6291cb0ef41Sopenharmony_ci in = have; 6301cb0ef41Sopenharmony_ci out = left; 6311cb0ef41Sopenharmony_ci ret = Z_OK; 6321cb0ef41Sopenharmony_ci for (;;) 6331cb0ef41Sopenharmony_ci switch (state->mode) { 6341cb0ef41Sopenharmony_ci case HEAD: 6351cb0ef41Sopenharmony_ci if (state->wrap == 0) { 6361cb0ef41Sopenharmony_ci state->mode = TYPEDO; 6371cb0ef41Sopenharmony_ci break; 6381cb0ef41Sopenharmony_ci } 6391cb0ef41Sopenharmony_ci NEEDBITS(16); 6401cb0ef41Sopenharmony_ci#ifdef GUNZIP 6411cb0ef41Sopenharmony_ci if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ 6421cb0ef41Sopenharmony_ci if (state->wbits == 0) 6431cb0ef41Sopenharmony_ci state->wbits = 15; 6441cb0ef41Sopenharmony_ci state->check = crc32(0L, Z_NULL, 0); 6451cb0ef41Sopenharmony_ci CRC2(state->check, hold); 6461cb0ef41Sopenharmony_ci INITBITS(); 6471cb0ef41Sopenharmony_ci state->mode = FLAGS; 6481cb0ef41Sopenharmony_ci break; 6491cb0ef41Sopenharmony_ci } 6501cb0ef41Sopenharmony_ci if (state->head != Z_NULL) 6511cb0ef41Sopenharmony_ci state->head->done = -1; 6521cb0ef41Sopenharmony_ci if (!(state->wrap & 1) || /* check if zlib header allowed */ 6531cb0ef41Sopenharmony_ci#else 6541cb0ef41Sopenharmony_ci if ( 6551cb0ef41Sopenharmony_ci#endif 6561cb0ef41Sopenharmony_ci ((BITS(8) << 8) + (hold >> 8)) % 31) { 6571cb0ef41Sopenharmony_ci strm->msg = (char *)"incorrect header check"; 6581cb0ef41Sopenharmony_ci state->mode = BAD; 6591cb0ef41Sopenharmony_ci break; 6601cb0ef41Sopenharmony_ci } 6611cb0ef41Sopenharmony_ci if (BITS(4) != Z_DEFLATED) { 6621cb0ef41Sopenharmony_ci strm->msg = (char *)"unknown compression method"; 6631cb0ef41Sopenharmony_ci state->mode = BAD; 6641cb0ef41Sopenharmony_ci break; 6651cb0ef41Sopenharmony_ci } 6661cb0ef41Sopenharmony_ci DROPBITS(4); 6671cb0ef41Sopenharmony_ci len = BITS(4) + 8; 6681cb0ef41Sopenharmony_ci if (state->wbits == 0) 6691cb0ef41Sopenharmony_ci state->wbits = len; 6701cb0ef41Sopenharmony_ci if (len > 15 || len > state->wbits) { 6711cb0ef41Sopenharmony_ci strm->msg = (char *)"invalid window size"; 6721cb0ef41Sopenharmony_ci state->mode = BAD; 6731cb0ef41Sopenharmony_ci break; 6741cb0ef41Sopenharmony_ci } 6751cb0ef41Sopenharmony_ci state->dmax = 1U << len; 6761cb0ef41Sopenharmony_ci state->flags = 0; /* indicate zlib header */ 6771cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: zlib header ok\n")); 6781cb0ef41Sopenharmony_ci strm->adler = state->check = adler32(0L, Z_NULL, 0); 6791cb0ef41Sopenharmony_ci state->mode = hold & 0x200 ? DICTID : TYPE; 6801cb0ef41Sopenharmony_ci INITBITS(); 6811cb0ef41Sopenharmony_ci break; 6821cb0ef41Sopenharmony_ci#ifdef GUNZIP 6831cb0ef41Sopenharmony_ci case FLAGS: 6841cb0ef41Sopenharmony_ci NEEDBITS(16); 6851cb0ef41Sopenharmony_ci state->flags = (int)(hold); 6861cb0ef41Sopenharmony_ci if ((state->flags & 0xff) != Z_DEFLATED) { 6871cb0ef41Sopenharmony_ci strm->msg = (char *)"unknown compression method"; 6881cb0ef41Sopenharmony_ci state->mode = BAD; 6891cb0ef41Sopenharmony_ci break; 6901cb0ef41Sopenharmony_ci } 6911cb0ef41Sopenharmony_ci if (state->flags & 0xe000) { 6921cb0ef41Sopenharmony_ci strm->msg = (char *)"unknown header flags set"; 6931cb0ef41Sopenharmony_ci state->mode = BAD; 6941cb0ef41Sopenharmony_ci break; 6951cb0ef41Sopenharmony_ci } 6961cb0ef41Sopenharmony_ci if (state->head != Z_NULL) 6971cb0ef41Sopenharmony_ci state->head->text = (int)((hold >> 8) & 1); 6981cb0ef41Sopenharmony_ci if ((state->flags & 0x0200) && (state->wrap & 4)) 6991cb0ef41Sopenharmony_ci CRC2(state->check, hold); 7001cb0ef41Sopenharmony_ci INITBITS(); 7011cb0ef41Sopenharmony_ci state->mode = TIME; 7021cb0ef41Sopenharmony_ci /* fallthrough */ 7031cb0ef41Sopenharmony_ci case TIME: 7041cb0ef41Sopenharmony_ci NEEDBITS(32); 7051cb0ef41Sopenharmony_ci if (state->head != Z_NULL) 7061cb0ef41Sopenharmony_ci state->head->time = hold; 7071cb0ef41Sopenharmony_ci if ((state->flags & 0x0200) && (state->wrap & 4)) 7081cb0ef41Sopenharmony_ci CRC4(state->check, hold); 7091cb0ef41Sopenharmony_ci INITBITS(); 7101cb0ef41Sopenharmony_ci state->mode = OS; 7111cb0ef41Sopenharmony_ci /* fallthrough */ 7121cb0ef41Sopenharmony_ci case OS: 7131cb0ef41Sopenharmony_ci NEEDBITS(16); 7141cb0ef41Sopenharmony_ci if (state->head != Z_NULL) { 7151cb0ef41Sopenharmony_ci state->head->xflags = (int)(hold & 0xff); 7161cb0ef41Sopenharmony_ci state->head->os = (int)(hold >> 8); 7171cb0ef41Sopenharmony_ci } 7181cb0ef41Sopenharmony_ci if ((state->flags & 0x0200) && (state->wrap & 4)) 7191cb0ef41Sopenharmony_ci CRC2(state->check, hold); 7201cb0ef41Sopenharmony_ci INITBITS(); 7211cb0ef41Sopenharmony_ci state->mode = EXLEN; 7221cb0ef41Sopenharmony_ci /* fallthrough */ 7231cb0ef41Sopenharmony_ci case EXLEN: 7241cb0ef41Sopenharmony_ci if (state->flags & 0x0400) { 7251cb0ef41Sopenharmony_ci NEEDBITS(16); 7261cb0ef41Sopenharmony_ci state->length = (unsigned)(hold); 7271cb0ef41Sopenharmony_ci if (state->head != Z_NULL) 7281cb0ef41Sopenharmony_ci state->head->extra_len = (unsigned)hold; 7291cb0ef41Sopenharmony_ci if ((state->flags & 0x0200) && (state->wrap & 4)) 7301cb0ef41Sopenharmony_ci CRC2(state->check, hold); 7311cb0ef41Sopenharmony_ci INITBITS(); 7321cb0ef41Sopenharmony_ci } 7331cb0ef41Sopenharmony_ci else if (state->head != Z_NULL) 7341cb0ef41Sopenharmony_ci state->head->extra = Z_NULL; 7351cb0ef41Sopenharmony_ci state->mode = EXTRA; 7361cb0ef41Sopenharmony_ci /* fallthrough */ 7371cb0ef41Sopenharmony_ci case EXTRA: 7381cb0ef41Sopenharmony_ci if (state->flags & 0x0400) { 7391cb0ef41Sopenharmony_ci copy = state->length; 7401cb0ef41Sopenharmony_ci if (copy > have) copy = have; 7411cb0ef41Sopenharmony_ci if (copy) { 7421cb0ef41Sopenharmony_ci if (state->head != Z_NULL && 7431cb0ef41Sopenharmony_ci state->head->extra != Z_NULL && 7441cb0ef41Sopenharmony_ci (len = state->head->extra_len - state->length) < 7451cb0ef41Sopenharmony_ci state->head->extra_max) { 7461cb0ef41Sopenharmony_ci zmemcpy(state->head->extra + len, next, 7471cb0ef41Sopenharmony_ci len + copy > state->head->extra_max ? 7481cb0ef41Sopenharmony_ci state->head->extra_max - len : copy); 7491cb0ef41Sopenharmony_ci } 7501cb0ef41Sopenharmony_ci if ((state->flags & 0x0200) && (state->wrap & 4)) 7511cb0ef41Sopenharmony_ci state->check = crc32(state->check, next, copy); 7521cb0ef41Sopenharmony_ci have -= copy; 7531cb0ef41Sopenharmony_ci next += copy; 7541cb0ef41Sopenharmony_ci state->length -= copy; 7551cb0ef41Sopenharmony_ci } 7561cb0ef41Sopenharmony_ci if (state->length) goto inf_leave; 7571cb0ef41Sopenharmony_ci } 7581cb0ef41Sopenharmony_ci state->length = 0; 7591cb0ef41Sopenharmony_ci state->mode = NAME; 7601cb0ef41Sopenharmony_ci /* fallthrough */ 7611cb0ef41Sopenharmony_ci case NAME: 7621cb0ef41Sopenharmony_ci if (state->flags & 0x0800) { 7631cb0ef41Sopenharmony_ci if (have == 0) goto inf_leave; 7641cb0ef41Sopenharmony_ci copy = 0; 7651cb0ef41Sopenharmony_ci do { 7661cb0ef41Sopenharmony_ci len = (unsigned)(next[copy++]); 7671cb0ef41Sopenharmony_ci if (state->head != Z_NULL && 7681cb0ef41Sopenharmony_ci state->head->name != Z_NULL && 7691cb0ef41Sopenharmony_ci state->length < state->head->name_max) 7701cb0ef41Sopenharmony_ci state->head->name[state->length++] = (Bytef)len; 7711cb0ef41Sopenharmony_ci } while (len && copy < have); 7721cb0ef41Sopenharmony_ci if ((state->flags & 0x0200) && (state->wrap & 4)) 7731cb0ef41Sopenharmony_ci state->check = crc32(state->check, next, copy); 7741cb0ef41Sopenharmony_ci have -= copy; 7751cb0ef41Sopenharmony_ci next += copy; 7761cb0ef41Sopenharmony_ci if (len) goto inf_leave; 7771cb0ef41Sopenharmony_ci } 7781cb0ef41Sopenharmony_ci else if (state->head != Z_NULL) 7791cb0ef41Sopenharmony_ci state->head->name = Z_NULL; 7801cb0ef41Sopenharmony_ci state->length = 0; 7811cb0ef41Sopenharmony_ci state->mode = COMMENT; 7821cb0ef41Sopenharmony_ci /* fallthrough */ 7831cb0ef41Sopenharmony_ci case COMMENT: 7841cb0ef41Sopenharmony_ci if (state->flags & 0x1000) { 7851cb0ef41Sopenharmony_ci if (have == 0) goto inf_leave; 7861cb0ef41Sopenharmony_ci copy = 0; 7871cb0ef41Sopenharmony_ci do { 7881cb0ef41Sopenharmony_ci len = (unsigned)(next[copy++]); 7891cb0ef41Sopenharmony_ci if (state->head != Z_NULL && 7901cb0ef41Sopenharmony_ci state->head->comment != Z_NULL && 7911cb0ef41Sopenharmony_ci state->length < state->head->comm_max) 7921cb0ef41Sopenharmony_ci state->head->comment[state->length++] = (Bytef)len; 7931cb0ef41Sopenharmony_ci } while (len && copy < have); 7941cb0ef41Sopenharmony_ci if ((state->flags & 0x0200) && (state->wrap & 4)) 7951cb0ef41Sopenharmony_ci state->check = crc32(state->check, next, copy); 7961cb0ef41Sopenharmony_ci have -= copy; 7971cb0ef41Sopenharmony_ci next += copy; 7981cb0ef41Sopenharmony_ci if (len) goto inf_leave; 7991cb0ef41Sopenharmony_ci } 8001cb0ef41Sopenharmony_ci else if (state->head != Z_NULL) 8011cb0ef41Sopenharmony_ci state->head->comment = Z_NULL; 8021cb0ef41Sopenharmony_ci state->mode = HCRC; 8031cb0ef41Sopenharmony_ci /* fallthrough */ 8041cb0ef41Sopenharmony_ci case HCRC: 8051cb0ef41Sopenharmony_ci if (state->flags & 0x0200) { 8061cb0ef41Sopenharmony_ci NEEDBITS(16); 8071cb0ef41Sopenharmony_ci if ((state->wrap & 4) && hold != (state->check & 0xffff)) { 8081cb0ef41Sopenharmony_ci strm->msg = (char *)"header crc mismatch"; 8091cb0ef41Sopenharmony_ci state->mode = BAD; 8101cb0ef41Sopenharmony_ci break; 8111cb0ef41Sopenharmony_ci } 8121cb0ef41Sopenharmony_ci INITBITS(); 8131cb0ef41Sopenharmony_ci } 8141cb0ef41Sopenharmony_ci if (state->head != Z_NULL) { 8151cb0ef41Sopenharmony_ci state->head->hcrc = (int)((state->flags >> 9) & 1); 8161cb0ef41Sopenharmony_ci state->head->done = 1; 8171cb0ef41Sopenharmony_ci } 8181cb0ef41Sopenharmony_ci strm->adler = state->check = crc32(0L, Z_NULL, 0); 8191cb0ef41Sopenharmony_ci state->mode = TYPE; 8201cb0ef41Sopenharmony_ci break; 8211cb0ef41Sopenharmony_ci#endif 8221cb0ef41Sopenharmony_ci case DICTID: 8231cb0ef41Sopenharmony_ci NEEDBITS(32); 8241cb0ef41Sopenharmony_ci strm->adler = state->check = ZSWAP32(hold); 8251cb0ef41Sopenharmony_ci INITBITS(); 8261cb0ef41Sopenharmony_ci state->mode = DICT; 8271cb0ef41Sopenharmony_ci /* fallthrough */ 8281cb0ef41Sopenharmony_ci case DICT: 8291cb0ef41Sopenharmony_ci if (state->havedict == 0) { 8301cb0ef41Sopenharmony_ci RESTORE(); 8311cb0ef41Sopenharmony_ci return Z_NEED_DICT; 8321cb0ef41Sopenharmony_ci } 8331cb0ef41Sopenharmony_ci strm->adler = state->check = adler32(0L, Z_NULL, 0); 8341cb0ef41Sopenharmony_ci state->mode = TYPE; 8351cb0ef41Sopenharmony_ci /* fallthrough */ 8361cb0ef41Sopenharmony_ci case TYPE: 8371cb0ef41Sopenharmony_ci if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; 8381cb0ef41Sopenharmony_ci /* fallthrough */ 8391cb0ef41Sopenharmony_ci case TYPEDO: 8401cb0ef41Sopenharmony_ci if (state->last) { 8411cb0ef41Sopenharmony_ci BYTEBITS(); 8421cb0ef41Sopenharmony_ci state->mode = CHECK; 8431cb0ef41Sopenharmony_ci break; 8441cb0ef41Sopenharmony_ci } 8451cb0ef41Sopenharmony_ci NEEDBITS(3); 8461cb0ef41Sopenharmony_ci state->last = BITS(1); 8471cb0ef41Sopenharmony_ci DROPBITS(1); 8481cb0ef41Sopenharmony_ci switch (BITS(2)) { 8491cb0ef41Sopenharmony_ci case 0: /* stored block */ 8501cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: stored block%s\n", 8511cb0ef41Sopenharmony_ci state->last ? " (last)" : "")); 8521cb0ef41Sopenharmony_ci state->mode = STORED; 8531cb0ef41Sopenharmony_ci break; 8541cb0ef41Sopenharmony_ci case 1: /* fixed block */ 8551cb0ef41Sopenharmony_ci fixedtables(state); 8561cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: fixed codes block%s\n", 8571cb0ef41Sopenharmony_ci state->last ? " (last)" : "")); 8581cb0ef41Sopenharmony_ci state->mode = LEN_; /* decode codes */ 8591cb0ef41Sopenharmony_ci if (flush == Z_TREES) { 8601cb0ef41Sopenharmony_ci DROPBITS(2); 8611cb0ef41Sopenharmony_ci goto inf_leave; 8621cb0ef41Sopenharmony_ci } 8631cb0ef41Sopenharmony_ci break; 8641cb0ef41Sopenharmony_ci case 2: /* dynamic block */ 8651cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: dynamic codes block%s\n", 8661cb0ef41Sopenharmony_ci state->last ? " (last)" : "")); 8671cb0ef41Sopenharmony_ci state->mode = TABLE; 8681cb0ef41Sopenharmony_ci break; 8691cb0ef41Sopenharmony_ci case 3: 8701cb0ef41Sopenharmony_ci strm->msg = (char *)"invalid block type"; 8711cb0ef41Sopenharmony_ci state->mode = BAD; 8721cb0ef41Sopenharmony_ci } 8731cb0ef41Sopenharmony_ci DROPBITS(2); 8741cb0ef41Sopenharmony_ci break; 8751cb0ef41Sopenharmony_ci case STORED: 8761cb0ef41Sopenharmony_ci BYTEBITS(); /* go to byte boundary */ 8771cb0ef41Sopenharmony_ci NEEDBITS(32); 8781cb0ef41Sopenharmony_ci if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { 8791cb0ef41Sopenharmony_ci strm->msg = (char *)"invalid stored block lengths"; 8801cb0ef41Sopenharmony_ci state->mode = BAD; 8811cb0ef41Sopenharmony_ci break; 8821cb0ef41Sopenharmony_ci } 8831cb0ef41Sopenharmony_ci state->length = (unsigned)hold & 0xffff; 8841cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: stored length %u\n", 8851cb0ef41Sopenharmony_ci state->length)); 8861cb0ef41Sopenharmony_ci INITBITS(); 8871cb0ef41Sopenharmony_ci state->mode = COPY_; 8881cb0ef41Sopenharmony_ci if (flush == Z_TREES) goto inf_leave; 8891cb0ef41Sopenharmony_ci /* fallthrough */ 8901cb0ef41Sopenharmony_ci case COPY_: 8911cb0ef41Sopenharmony_ci state->mode = COPY; 8921cb0ef41Sopenharmony_ci /* fallthrough */ 8931cb0ef41Sopenharmony_ci case COPY: 8941cb0ef41Sopenharmony_ci copy = state->length; 8951cb0ef41Sopenharmony_ci if (copy) { 8961cb0ef41Sopenharmony_ci if (copy > have) copy = have; 8971cb0ef41Sopenharmony_ci if (copy > left) copy = left; 8981cb0ef41Sopenharmony_ci if (copy == 0) goto inf_leave; 8991cb0ef41Sopenharmony_ci zmemcpy(put, next, copy); 9001cb0ef41Sopenharmony_ci have -= copy; 9011cb0ef41Sopenharmony_ci next += copy; 9021cb0ef41Sopenharmony_ci left -= copy; 9031cb0ef41Sopenharmony_ci put += copy; 9041cb0ef41Sopenharmony_ci state->length -= copy; 9051cb0ef41Sopenharmony_ci break; 9061cb0ef41Sopenharmony_ci } 9071cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: stored end\n")); 9081cb0ef41Sopenharmony_ci state->mode = TYPE; 9091cb0ef41Sopenharmony_ci break; 9101cb0ef41Sopenharmony_ci case TABLE: 9111cb0ef41Sopenharmony_ci NEEDBITS(14); 9121cb0ef41Sopenharmony_ci state->nlen = BITS(5) + 257; 9131cb0ef41Sopenharmony_ci DROPBITS(5); 9141cb0ef41Sopenharmony_ci state->ndist = BITS(5) + 1; 9151cb0ef41Sopenharmony_ci DROPBITS(5); 9161cb0ef41Sopenharmony_ci state->ncode = BITS(4) + 4; 9171cb0ef41Sopenharmony_ci DROPBITS(4); 9181cb0ef41Sopenharmony_ci#ifndef PKZIP_BUG_WORKAROUND 9191cb0ef41Sopenharmony_ci if (state->nlen > 286 || state->ndist > 30) { 9201cb0ef41Sopenharmony_ci strm->msg = (char *)"too many length or distance symbols"; 9211cb0ef41Sopenharmony_ci state->mode = BAD; 9221cb0ef41Sopenharmony_ci break; 9231cb0ef41Sopenharmony_ci } 9241cb0ef41Sopenharmony_ci#endif 9251cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: table sizes ok\n")); 9261cb0ef41Sopenharmony_ci state->have = 0; 9271cb0ef41Sopenharmony_ci state->mode = LENLENS; 9281cb0ef41Sopenharmony_ci /* fallthrough */ 9291cb0ef41Sopenharmony_ci case LENLENS: 9301cb0ef41Sopenharmony_ci while (state->have < state->ncode) { 9311cb0ef41Sopenharmony_ci NEEDBITS(3); 9321cb0ef41Sopenharmony_ci state->lens[order[state->have++]] = (unsigned short)BITS(3); 9331cb0ef41Sopenharmony_ci DROPBITS(3); 9341cb0ef41Sopenharmony_ci } 9351cb0ef41Sopenharmony_ci while (state->have < 19) 9361cb0ef41Sopenharmony_ci state->lens[order[state->have++]] = 0; 9371cb0ef41Sopenharmony_ci state->next = state->codes; 9381cb0ef41Sopenharmony_ci state->lencode = (const code FAR *)(state->next); 9391cb0ef41Sopenharmony_ci state->lenbits = 7; 9401cb0ef41Sopenharmony_ci ret = inflate_table(CODES, state->lens, 19, &(state->next), 9411cb0ef41Sopenharmony_ci &(state->lenbits), state->work); 9421cb0ef41Sopenharmony_ci if (ret) { 9431cb0ef41Sopenharmony_ci strm->msg = (char *)"invalid code lengths set"; 9441cb0ef41Sopenharmony_ci state->mode = BAD; 9451cb0ef41Sopenharmony_ci break; 9461cb0ef41Sopenharmony_ci } 9471cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: code lengths ok\n")); 9481cb0ef41Sopenharmony_ci state->have = 0; 9491cb0ef41Sopenharmony_ci state->mode = CODELENS; 9501cb0ef41Sopenharmony_ci /* fallthrough */ 9511cb0ef41Sopenharmony_ci case CODELENS: 9521cb0ef41Sopenharmony_ci while (state->have < state->nlen + state->ndist) { 9531cb0ef41Sopenharmony_ci for (;;) { 9541cb0ef41Sopenharmony_ci here = state->lencode[BITS(state->lenbits)]; 9551cb0ef41Sopenharmony_ci if ((unsigned)(here.bits) <= bits) break; 9561cb0ef41Sopenharmony_ci PULLBYTE(); 9571cb0ef41Sopenharmony_ci } 9581cb0ef41Sopenharmony_ci if (here.val < 16) { 9591cb0ef41Sopenharmony_ci DROPBITS(here.bits); 9601cb0ef41Sopenharmony_ci state->lens[state->have++] = here.val; 9611cb0ef41Sopenharmony_ci } 9621cb0ef41Sopenharmony_ci else { 9631cb0ef41Sopenharmony_ci if (here.val == 16) { 9641cb0ef41Sopenharmony_ci NEEDBITS(here.bits + 2); 9651cb0ef41Sopenharmony_ci DROPBITS(here.bits); 9661cb0ef41Sopenharmony_ci if (state->have == 0) { 9671cb0ef41Sopenharmony_ci strm->msg = (char *)"invalid bit length repeat"; 9681cb0ef41Sopenharmony_ci state->mode = BAD; 9691cb0ef41Sopenharmony_ci break; 9701cb0ef41Sopenharmony_ci } 9711cb0ef41Sopenharmony_ci len = state->lens[state->have - 1]; 9721cb0ef41Sopenharmony_ci copy = 3 + BITS(2); 9731cb0ef41Sopenharmony_ci DROPBITS(2); 9741cb0ef41Sopenharmony_ci } 9751cb0ef41Sopenharmony_ci else if (here.val == 17) { 9761cb0ef41Sopenharmony_ci NEEDBITS(here.bits + 3); 9771cb0ef41Sopenharmony_ci DROPBITS(here.bits); 9781cb0ef41Sopenharmony_ci len = 0; 9791cb0ef41Sopenharmony_ci copy = 3 + BITS(3); 9801cb0ef41Sopenharmony_ci DROPBITS(3); 9811cb0ef41Sopenharmony_ci } 9821cb0ef41Sopenharmony_ci else { 9831cb0ef41Sopenharmony_ci NEEDBITS(here.bits + 7); 9841cb0ef41Sopenharmony_ci DROPBITS(here.bits); 9851cb0ef41Sopenharmony_ci len = 0; 9861cb0ef41Sopenharmony_ci copy = 11 + BITS(7); 9871cb0ef41Sopenharmony_ci DROPBITS(7); 9881cb0ef41Sopenharmony_ci } 9891cb0ef41Sopenharmony_ci if (state->have + copy > state->nlen + state->ndist) { 9901cb0ef41Sopenharmony_ci strm->msg = (char *)"invalid bit length repeat"; 9911cb0ef41Sopenharmony_ci state->mode = BAD; 9921cb0ef41Sopenharmony_ci break; 9931cb0ef41Sopenharmony_ci } 9941cb0ef41Sopenharmony_ci while (copy--) 9951cb0ef41Sopenharmony_ci state->lens[state->have++] = (unsigned short)len; 9961cb0ef41Sopenharmony_ci } 9971cb0ef41Sopenharmony_ci } 9981cb0ef41Sopenharmony_ci 9991cb0ef41Sopenharmony_ci /* handle error breaks in while */ 10001cb0ef41Sopenharmony_ci if (state->mode == BAD) break; 10011cb0ef41Sopenharmony_ci 10021cb0ef41Sopenharmony_ci /* check for end-of-block code (better have one) */ 10031cb0ef41Sopenharmony_ci if (state->lens[256] == 0) { 10041cb0ef41Sopenharmony_ci strm->msg = (char *)"invalid code -- missing end-of-block"; 10051cb0ef41Sopenharmony_ci state->mode = BAD; 10061cb0ef41Sopenharmony_ci break; 10071cb0ef41Sopenharmony_ci } 10081cb0ef41Sopenharmony_ci 10091cb0ef41Sopenharmony_ci /* build code tables -- note: do not change the lenbits or distbits 10101cb0ef41Sopenharmony_ci values here (10 and 9) without reading the comments in inftrees.h 10111cb0ef41Sopenharmony_ci concerning the ENOUGH constants, which depend on those values */ 10121cb0ef41Sopenharmony_ci state->next = state->codes; 10131cb0ef41Sopenharmony_ci state->lencode = (const code FAR *)(state->next); 10141cb0ef41Sopenharmony_ci state->lenbits = 10; 10151cb0ef41Sopenharmony_ci ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), 10161cb0ef41Sopenharmony_ci &(state->lenbits), state->work); 10171cb0ef41Sopenharmony_ci if (ret) { 10181cb0ef41Sopenharmony_ci strm->msg = (char *)"invalid literal/lengths set"; 10191cb0ef41Sopenharmony_ci state->mode = BAD; 10201cb0ef41Sopenharmony_ci break; 10211cb0ef41Sopenharmony_ci } 10221cb0ef41Sopenharmony_ci state->distcode = (const code FAR *)(state->next); 10231cb0ef41Sopenharmony_ci state->distbits = 9; 10241cb0ef41Sopenharmony_ci ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, 10251cb0ef41Sopenharmony_ci &(state->next), &(state->distbits), state->work); 10261cb0ef41Sopenharmony_ci if (ret) { 10271cb0ef41Sopenharmony_ci strm->msg = (char *)"invalid distances set"; 10281cb0ef41Sopenharmony_ci state->mode = BAD; 10291cb0ef41Sopenharmony_ci break; 10301cb0ef41Sopenharmony_ci } 10311cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: codes ok\n")); 10321cb0ef41Sopenharmony_ci state->mode = LEN_; 10331cb0ef41Sopenharmony_ci if (flush == Z_TREES) goto inf_leave; 10341cb0ef41Sopenharmony_ci /* fallthrough */ 10351cb0ef41Sopenharmony_ci case LEN_: 10361cb0ef41Sopenharmony_ci state->mode = LEN; 10371cb0ef41Sopenharmony_ci /* fallthrough */ 10381cb0ef41Sopenharmony_ci case LEN: 10391cb0ef41Sopenharmony_ci if (have >= INFLATE_FAST_MIN_INPUT && 10401cb0ef41Sopenharmony_ci left >= INFLATE_FAST_MIN_OUTPUT) { 10411cb0ef41Sopenharmony_ci RESTORE(); 10421cb0ef41Sopenharmony_ci inflate_fast_chunk_(strm, out); 10431cb0ef41Sopenharmony_ci LOAD(); 10441cb0ef41Sopenharmony_ci if (state->mode == TYPE) 10451cb0ef41Sopenharmony_ci state->back = -1; 10461cb0ef41Sopenharmony_ci break; 10471cb0ef41Sopenharmony_ci } 10481cb0ef41Sopenharmony_ci state->back = 0; 10491cb0ef41Sopenharmony_ci for (;;) { 10501cb0ef41Sopenharmony_ci here = state->lencode[BITS(state->lenbits)]; 10511cb0ef41Sopenharmony_ci if ((unsigned)(here.bits) <= bits) break; 10521cb0ef41Sopenharmony_ci PULLBYTE(); 10531cb0ef41Sopenharmony_ci } 10541cb0ef41Sopenharmony_ci if (here.op && (here.op & 0xf0) == 0) { 10551cb0ef41Sopenharmony_ci last = here; 10561cb0ef41Sopenharmony_ci for (;;) { 10571cb0ef41Sopenharmony_ci here = state->lencode[last.val + 10581cb0ef41Sopenharmony_ci (BITS(last.bits + last.op) >> last.bits)]; 10591cb0ef41Sopenharmony_ci if ((unsigned)(last.bits + here.bits) <= bits) break; 10601cb0ef41Sopenharmony_ci PULLBYTE(); 10611cb0ef41Sopenharmony_ci } 10621cb0ef41Sopenharmony_ci DROPBITS(last.bits); 10631cb0ef41Sopenharmony_ci state->back += last.bits; 10641cb0ef41Sopenharmony_ci } 10651cb0ef41Sopenharmony_ci DROPBITS(here.bits); 10661cb0ef41Sopenharmony_ci state->back += here.bits; 10671cb0ef41Sopenharmony_ci state->length = (unsigned)here.val; 10681cb0ef41Sopenharmony_ci if ((int)(here.op) == 0) { 10691cb0ef41Sopenharmony_ci Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 10701cb0ef41Sopenharmony_ci "inflate: literal '%c'\n" : 10711cb0ef41Sopenharmony_ci "inflate: literal 0x%02x\n", here.val)); 10721cb0ef41Sopenharmony_ci state->mode = LIT; 10731cb0ef41Sopenharmony_ci break; 10741cb0ef41Sopenharmony_ci } 10751cb0ef41Sopenharmony_ci if (here.op & 32) { 10761cb0ef41Sopenharmony_ci Tracevv((stderr, "inflate: end of block\n")); 10771cb0ef41Sopenharmony_ci state->back = -1; 10781cb0ef41Sopenharmony_ci state->mode = TYPE; 10791cb0ef41Sopenharmony_ci break; 10801cb0ef41Sopenharmony_ci } 10811cb0ef41Sopenharmony_ci if (here.op & 64) { 10821cb0ef41Sopenharmony_ci strm->msg = (char *)"invalid literal/length code"; 10831cb0ef41Sopenharmony_ci state->mode = BAD; 10841cb0ef41Sopenharmony_ci break; 10851cb0ef41Sopenharmony_ci } 10861cb0ef41Sopenharmony_ci state->extra = (unsigned)(here.op) & 15; 10871cb0ef41Sopenharmony_ci state->mode = LENEXT; 10881cb0ef41Sopenharmony_ci /* fallthrough */ 10891cb0ef41Sopenharmony_ci case LENEXT: 10901cb0ef41Sopenharmony_ci if (state->extra) { 10911cb0ef41Sopenharmony_ci NEEDBITS(state->extra); 10921cb0ef41Sopenharmony_ci state->length += BITS(state->extra); 10931cb0ef41Sopenharmony_ci DROPBITS(state->extra); 10941cb0ef41Sopenharmony_ci state->back += state->extra; 10951cb0ef41Sopenharmony_ci } 10961cb0ef41Sopenharmony_ci Tracevv((stderr, "inflate: length %u\n", state->length)); 10971cb0ef41Sopenharmony_ci state->was = state->length; 10981cb0ef41Sopenharmony_ci state->mode = DIST; 10991cb0ef41Sopenharmony_ci /* fallthrough */ 11001cb0ef41Sopenharmony_ci case DIST: 11011cb0ef41Sopenharmony_ci for (;;) { 11021cb0ef41Sopenharmony_ci here = state->distcode[BITS(state->distbits)]; 11031cb0ef41Sopenharmony_ci if ((unsigned)(here.bits) <= bits) break; 11041cb0ef41Sopenharmony_ci PULLBYTE(); 11051cb0ef41Sopenharmony_ci } 11061cb0ef41Sopenharmony_ci if ((here.op & 0xf0) == 0) { 11071cb0ef41Sopenharmony_ci last = here; 11081cb0ef41Sopenharmony_ci for (;;) { 11091cb0ef41Sopenharmony_ci here = state->distcode[last.val + 11101cb0ef41Sopenharmony_ci (BITS(last.bits + last.op) >> last.bits)]; 11111cb0ef41Sopenharmony_ci if ((unsigned)(last.bits + here.bits) <= bits) break; 11121cb0ef41Sopenharmony_ci PULLBYTE(); 11131cb0ef41Sopenharmony_ci } 11141cb0ef41Sopenharmony_ci DROPBITS(last.bits); 11151cb0ef41Sopenharmony_ci state->back += last.bits; 11161cb0ef41Sopenharmony_ci } 11171cb0ef41Sopenharmony_ci DROPBITS(here.bits); 11181cb0ef41Sopenharmony_ci state->back += here.bits; 11191cb0ef41Sopenharmony_ci if (here.op & 64) { 11201cb0ef41Sopenharmony_ci strm->msg = (char *)"invalid distance code"; 11211cb0ef41Sopenharmony_ci state->mode = BAD; 11221cb0ef41Sopenharmony_ci break; 11231cb0ef41Sopenharmony_ci } 11241cb0ef41Sopenharmony_ci state->offset = (unsigned)here.val; 11251cb0ef41Sopenharmony_ci state->extra = (unsigned)(here.op) & 15; 11261cb0ef41Sopenharmony_ci state->mode = DISTEXT; 11271cb0ef41Sopenharmony_ci /* fallthrough */ 11281cb0ef41Sopenharmony_ci case DISTEXT: 11291cb0ef41Sopenharmony_ci if (state->extra) { 11301cb0ef41Sopenharmony_ci NEEDBITS(state->extra); 11311cb0ef41Sopenharmony_ci state->offset += BITS(state->extra); 11321cb0ef41Sopenharmony_ci DROPBITS(state->extra); 11331cb0ef41Sopenharmony_ci state->back += state->extra; 11341cb0ef41Sopenharmony_ci } 11351cb0ef41Sopenharmony_ci#ifdef INFLATE_STRICT 11361cb0ef41Sopenharmony_ci if (state->offset > state->dmax) { 11371cb0ef41Sopenharmony_ci strm->msg = (char *)"invalid distance too far back"; 11381cb0ef41Sopenharmony_ci state->mode = BAD; 11391cb0ef41Sopenharmony_ci break; 11401cb0ef41Sopenharmony_ci } 11411cb0ef41Sopenharmony_ci#endif 11421cb0ef41Sopenharmony_ci Tracevv((stderr, "inflate: distance %u\n", state->offset)); 11431cb0ef41Sopenharmony_ci state->mode = MATCH; 11441cb0ef41Sopenharmony_ci /* fallthrough */ 11451cb0ef41Sopenharmony_ci case MATCH: 11461cb0ef41Sopenharmony_ci if (left == 0) goto inf_leave; 11471cb0ef41Sopenharmony_ci copy = out - left; 11481cb0ef41Sopenharmony_ci if (state->offset > copy) { /* copy from window */ 11491cb0ef41Sopenharmony_ci copy = state->offset - copy; 11501cb0ef41Sopenharmony_ci if (copy > state->whave) { 11511cb0ef41Sopenharmony_ci if (state->sane) { 11521cb0ef41Sopenharmony_ci strm->msg = (char *)"invalid distance too far back"; 11531cb0ef41Sopenharmony_ci state->mode = BAD; 11541cb0ef41Sopenharmony_ci break; 11551cb0ef41Sopenharmony_ci } 11561cb0ef41Sopenharmony_ci#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 11571cb0ef41Sopenharmony_ci Trace((stderr, "inflate.c too far\n")); 11581cb0ef41Sopenharmony_ci copy -= state->whave; 11591cb0ef41Sopenharmony_ci if (copy > state->length) copy = state->length; 11601cb0ef41Sopenharmony_ci if (copy > left) copy = left; 11611cb0ef41Sopenharmony_ci left -= copy; 11621cb0ef41Sopenharmony_ci state->length -= copy; 11631cb0ef41Sopenharmony_ci do { 11641cb0ef41Sopenharmony_ci *put++ = 0; 11651cb0ef41Sopenharmony_ci } while (--copy); 11661cb0ef41Sopenharmony_ci if (state->length == 0) state->mode = LEN; 11671cb0ef41Sopenharmony_ci break; 11681cb0ef41Sopenharmony_ci#endif 11691cb0ef41Sopenharmony_ci } 11701cb0ef41Sopenharmony_ci if (copy > state->wnext) { 11711cb0ef41Sopenharmony_ci copy -= state->wnext; 11721cb0ef41Sopenharmony_ci from = state->window + (state->wsize - copy); 11731cb0ef41Sopenharmony_ci } 11741cb0ef41Sopenharmony_ci else 11751cb0ef41Sopenharmony_ci from = state->window + (state->wnext - copy); 11761cb0ef41Sopenharmony_ci if (copy > state->length) copy = state->length; 11771cb0ef41Sopenharmony_ci if (copy > left) copy = left; 11781cb0ef41Sopenharmony_ci put = chunkcopy_safe(put, from, copy, put + left); 11791cb0ef41Sopenharmony_ci } 11801cb0ef41Sopenharmony_ci else { /* copy from output */ 11811cb0ef41Sopenharmony_ci copy = state->length; 11821cb0ef41Sopenharmony_ci if (copy > left) copy = left; 11831cb0ef41Sopenharmony_ci put = chunkcopy_lapped_safe(put, state->offset, copy, put + left); 11841cb0ef41Sopenharmony_ci } 11851cb0ef41Sopenharmony_ci left -= copy; 11861cb0ef41Sopenharmony_ci state->length -= copy; 11871cb0ef41Sopenharmony_ci if (state->length == 0) state->mode = LEN; 11881cb0ef41Sopenharmony_ci break; 11891cb0ef41Sopenharmony_ci case LIT: 11901cb0ef41Sopenharmony_ci if (left == 0) goto inf_leave; 11911cb0ef41Sopenharmony_ci *put++ = (unsigned char)(state->length); 11921cb0ef41Sopenharmony_ci left--; 11931cb0ef41Sopenharmony_ci state->mode = LEN; 11941cb0ef41Sopenharmony_ci break; 11951cb0ef41Sopenharmony_ci case CHECK: 11961cb0ef41Sopenharmony_ci if (state->wrap) { 11971cb0ef41Sopenharmony_ci NEEDBITS(32); 11981cb0ef41Sopenharmony_ci out -= left; 11991cb0ef41Sopenharmony_ci strm->total_out += out; 12001cb0ef41Sopenharmony_ci state->total += out; 12011cb0ef41Sopenharmony_ci if ((state->wrap & 4) && out) 12021cb0ef41Sopenharmony_ci strm->adler = state->check = 12031cb0ef41Sopenharmony_ci UPDATE_CHECK(state->check, put - out, out); 12041cb0ef41Sopenharmony_ci out = left; 12051cb0ef41Sopenharmony_ci if ((state->wrap & 4) && ( 12061cb0ef41Sopenharmony_ci#ifdef GUNZIP 12071cb0ef41Sopenharmony_ci state->flags ? hold : 12081cb0ef41Sopenharmony_ci#endif 12091cb0ef41Sopenharmony_ci ZSWAP32(hold)) != state->check) { 12101cb0ef41Sopenharmony_ci strm->msg = (char *)"incorrect data check"; 12111cb0ef41Sopenharmony_ci state->mode = BAD; 12121cb0ef41Sopenharmony_ci break; 12131cb0ef41Sopenharmony_ci } 12141cb0ef41Sopenharmony_ci INITBITS(); 12151cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: check matches trailer\n")); 12161cb0ef41Sopenharmony_ci } 12171cb0ef41Sopenharmony_ci#ifdef GUNZIP 12181cb0ef41Sopenharmony_ci state->mode = LENGTH; 12191cb0ef41Sopenharmony_ci /* fallthrough */ 12201cb0ef41Sopenharmony_ci case LENGTH: 12211cb0ef41Sopenharmony_ci if (state->wrap && state->flags) { 12221cb0ef41Sopenharmony_ci NEEDBITS(32); 12231cb0ef41Sopenharmony_ci if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { 12241cb0ef41Sopenharmony_ci strm->msg = (char *)"incorrect length check"; 12251cb0ef41Sopenharmony_ci state->mode = BAD; 12261cb0ef41Sopenharmony_ci break; 12271cb0ef41Sopenharmony_ci } 12281cb0ef41Sopenharmony_ci INITBITS(); 12291cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: length matches trailer\n")); 12301cb0ef41Sopenharmony_ci } 12311cb0ef41Sopenharmony_ci#endif 12321cb0ef41Sopenharmony_ci state->mode = DONE; 12331cb0ef41Sopenharmony_ci /* fallthrough */ 12341cb0ef41Sopenharmony_ci case DONE: 12351cb0ef41Sopenharmony_ci ret = Z_STREAM_END; 12361cb0ef41Sopenharmony_ci goto inf_leave; 12371cb0ef41Sopenharmony_ci case BAD: 12381cb0ef41Sopenharmony_ci ret = Z_DATA_ERROR; 12391cb0ef41Sopenharmony_ci goto inf_leave; 12401cb0ef41Sopenharmony_ci case MEM: 12411cb0ef41Sopenharmony_ci return Z_MEM_ERROR; 12421cb0ef41Sopenharmony_ci case SYNC: 12431cb0ef41Sopenharmony_ci /* fallthrough */ 12441cb0ef41Sopenharmony_ci default: 12451cb0ef41Sopenharmony_ci return Z_STREAM_ERROR; 12461cb0ef41Sopenharmony_ci } 12471cb0ef41Sopenharmony_ci 12481cb0ef41Sopenharmony_ci /* 12491cb0ef41Sopenharmony_ci Return from inflate(), updating the total counts and the check value. 12501cb0ef41Sopenharmony_ci If there was no progress during the inflate() call, return a buffer 12511cb0ef41Sopenharmony_ci error. Call updatewindow() to create and/or update the window state. 12521cb0ef41Sopenharmony_ci Note: a memory error from inflate() is non-recoverable. 12531cb0ef41Sopenharmony_ci */ 12541cb0ef41Sopenharmony_ci inf_leave: 12551cb0ef41Sopenharmony_ci#if defined(ZLIB_DEBUG) 12561cb0ef41Sopenharmony_ci /* XXX(cavalcantii): I put this in place back in 2017 to help debug faulty 12571cb0ef41Sopenharmony_ci * client code relying on undefined behavior when chunk_copy first landed. 12581cb0ef41Sopenharmony_ci * 12591cb0ef41Sopenharmony_ci * It is save to say after all these years that Chromium code is well 12601cb0ef41Sopenharmony_ci * behaved and works fine with the optimization, therefore we can enable 12611cb0ef41Sopenharmony_ci * this only for DEBUG builds. 12621cb0ef41Sopenharmony_ci * 12631cb0ef41Sopenharmony_ci * We write a defined value in the unused space to help mark 12641cb0ef41Sopenharmony_ci * where the stream has ended. We don't use zeros as that can 12651cb0ef41Sopenharmony_ci * mislead clients relying on undefined behavior (i.e. assuming 12661cb0ef41Sopenharmony_ci * that the data is over when the buffer has a zero/null value). 12671cb0ef41Sopenharmony_ci * 12681cb0ef41Sopenharmony_ci * The basic idea is that if client code is not relying on the zlib context 12691cb0ef41Sopenharmony_ci * to inform the amount of decompressed data, but instead reads the output 12701cb0ef41Sopenharmony_ci * buffer until a zero/null is found, it will fail faster and harder 12711cb0ef41Sopenharmony_ci * when the remaining of the buffer is marked with a symbol (e.g. 0x55). 12721cb0ef41Sopenharmony_ci */ 12731cb0ef41Sopenharmony_ci if (left >= CHUNKCOPY_CHUNK_SIZE) 12741cb0ef41Sopenharmony_ci memset(put, 0x55, CHUNKCOPY_CHUNK_SIZE); 12751cb0ef41Sopenharmony_ci else 12761cb0ef41Sopenharmony_ci memset(put, 0x55, left); 12771cb0ef41Sopenharmony_ci#endif 12781cb0ef41Sopenharmony_ci RESTORE(); 12791cb0ef41Sopenharmony_ci if (state->wsize || (out != strm->avail_out && state->mode < BAD && 12801cb0ef41Sopenharmony_ci (state->mode < CHECK || flush != Z_FINISH))) 12811cb0ef41Sopenharmony_ci if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { 12821cb0ef41Sopenharmony_ci state->mode = MEM; 12831cb0ef41Sopenharmony_ci return Z_MEM_ERROR; 12841cb0ef41Sopenharmony_ci } 12851cb0ef41Sopenharmony_ci in -= strm->avail_in; 12861cb0ef41Sopenharmony_ci out -= strm->avail_out; 12871cb0ef41Sopenharmony_ci strm->total_in += in; 12881cb0ef41Sopenharmony_ci strm->total_out += out; 12891cb0ef41Sopenharmony_ci state->total += out; 12901cb0ef41Sopenharmony_ci if ((state->wrap & 4) && out) 12911cb0ef41Sopenharmony_ci strm->adler = state->check = 12921cb0ef41Sopenharmony_ci UPDATE_CHECK(state->check, strm->next_out - out, out); 12931cb0ef41Sopenharmony_ci strm->data_type = (int)state->bits + (state->last ? 64 : 0) + 12941cb0ef41Sopenharmony_ci (state->mode == TYPE ? 128 : 0) + 12951cb0ef41Sopenharmony_ci (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); 12961cb0ef41Sopenharmony_ci if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) 12971cb0ef41Sopenharmony_ci ret = Z_BUF_ERROR; 12981cb0ef41Sopenharmony_ci return ret; 12991cb0ef41Sopenharmony_ci} 13001cb0ef41Sopenharmony_ci 13011cb0ef41Sopenharmony_ciint ZEXPORT inflateEnd(z_streamp strm) { 13021cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 13031cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) 13041cb0ef41Sopenharmony_ci return Z_STREAM_ERROR; 13051cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 13061cb0ef41Sopenharmony_ci if (state->window != Z_NULL) ZFREE(strm, state->window); 13071cb0ef41Sopenharmony_ci ZFREE(strm, strm->state); 13081cb0ef41Sopenharmony_ci strm->state = Z_NULL; 13091cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: end\n")); 13101cb0ef41Sopenharmony_ci return Z_OK; 13111cb0ef41Sopenharmony_ci} 13121cb0ef41Sopenharmony_ci 13131cb0ef41Sopenharmony_ciint ZEXPORT inflateGetDictionary(z_streamp strm, Bytef *dictionary, 13141cb0ef41Sopenharmony_ci uInt *dictLength) { 13151cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 13161cb0ef41Sopenharmony_ci 13171cb0ef41Sopenharmony_ci /* check state */ 13181cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 13191cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 13201cb0ef41Sopenharmony_ci 13211cb0ef41Sopenharmony_ci /* copy dictionary */ 13221cb0ef41Sopenharmony_ci if (state->whave && dictionary != Z_NULL) { 13231cb0ef41Sopenharmony_ci zmemcpy(dictionary, state->window + state->wnext, 13241cb0ef41Sopenharmony_ci state->whave - state->wnext); 13251cb0ef41Sopenharmony_ci zmemcpy(dictionary + state->whave - state->wnext, 13261cb0ef41Sopenharmony_ci state->window, state->wnext); 13271cb0ef41Sopenharmony_ci } 13281cb0ef41Sopenharmony_ci if (dictLength != Z_NULL) 13291cb0ef41Sopenharmony_ci *dictLength = state->whave; 13301cb0ef41Sopenharmony_ci return Z_OK; 13311cb0ef41Sopenharmony_ci} 13321cb0ef41Sopenharmony_ci 13331cb0ef41Sopenharmony_ciint ZEXPORT inflateSetDictionary(z_streamp strm, const Bytef *dictionary, 13341cb0ef41Sopenharmony_ci uInt dictLength) { 13351cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 13361cb0ef41Sopenharmony_ci unsigned long dictid; 13371cb0ef41Sopenharmony_ci int ret; 13381cb0ef41Sopenharmony_ci 13391cb0ef41Sopenharmony_ci /* check state */ 13401cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 13411cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 13421cb0ef41Sopenharmony_ci if (state->wrap != 0 && state->mode != DICT) 13431cb0ef41Sopenharmony_ci return Z_STREAM_ERROR; 13441cb0ef41Sopenharmony_ci 13451cb0ef41Sopenharmony_ci /* check for correct dictionary identifier */ 13461cb0ef41Sopenharmony_ci if (state->mode == DICT) { 13471cb0ef41Sopenharmony_ci dictid = adler32(0L, Z_NULL, 0); 13481cb0ef41Sopenharmony_ci dictid = adler32(dictid, dictionary, dictLength); 13491cb0ef41Sopenharmony_ci if (dictid != state->check) 13501cb0ef41Sopenharmony_ci return Z_DATA_ERROR; 13511cb0ef41Sopenharmony_ci } 13521cb0ef41Sopenharmony_ci 13531cb0ef41Sopenharmony_ci /* copy dictionary to window using updatewindow(), which will amend the 13541cb0ef41Sopenharmony_ci existing dictionary if appropriate */ 13551cb0ef41Sopenharmony_ci ret = updatewindow(strm, dictionary + dictLength, dictLength); 13561cb0ef41Sopenharmony_ci if (ret) { 13571cb0ef41Sopenharmony_ci state->mode = MEM; 13581cb0ef41Sopenharmony_ci return Z_MEM_ERROR; 13591cb0ef41Sopenharmony_ci } 13601cb0ef41Sopenharmony_ci state->havedict = 1; 13611cb0ef41Sopenharmony_ci Tracev((stderr, "inflate: dictionary set\n")); 13621cb0ef41Sopenharmony_ci return Z_OK; 13631cb0ef41Sopenharmony_ci} 13641cb0ef41Sopenharmony_ci 13651cb0ef41Sopenharmony_ciint ZEXPORT inflateGetHeader(z_streamp strm, gz_headerp head) { 13661cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 13671cb0ef41Sopenharmony_ci 13681cb0ef41Sopenharmony_ci /* check state */ 13691cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 13701cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 13711cb0ef41Sopenharmony_ci if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; 13721cb0ef41Sopenharmony_ci 13731cb0ef41Sopenharmony_ci /* save header structure */ 13741cb0ef41Sopenharmony_ci state->head = head; 13751cb0ef41Sopenharmony_ci head->done = 0; 13761cb0ef41Sopenharmony_ci return Z_OK; 13771cb0ef41Sopenharmony_ci} 13781cb0ef41Sopenharmony_ci 13791cb0ef41Sopenharmony_ci/* 13801cb0ef41Sopenharmony_ci Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found 13811cb0ef41Sopenharmony_ci or when out of input. When called, *have is the number of pattern bytes 13821cb0ef41Sopenharmony_ci found in order so far, in 0..3. On return *have is updated to the new 13831cb0ef41Sopenharmony_ci state. If on return *have equals four, then the pattern was found and the 13841cb0ef41Sopenharmony_ci return value is how many bytes were read including the last byte of the 13851cb0ef41Sopenharmony_ci pattern. If *have is less than four, then the pattern has not been found 13861cb0ef41Sopenharmony_ci yet and the return value is len. In the latter case, syncsearch() can be 13871cb0ef41Sopenharmony_ci called again with more data and the *have state. *have is initialized to 13881cb0ef41Sopenharmony_ci zero for the first call. 13891cb0ef41Sopenharmony_ci */ 13901cb0ef41Sopenharmony_cilocal unsigned syncsearch(unsigned FAR *have, const unsigned char FAR *buf, 13911cb0ef41Sopenharmony_ci unsigned len) { 13921cb0ef41Sopenharmony_ci unsigned got; 13931cb0ef41Sopenharmony_ci unsigned next; 13941cb0ef41Sopenharmony_ci 13951cb0ef41Sopenharmony_ci got = *have; 13961cb0ef41Sopenharmony_ci next = 0; 13971cb0ef41Sopenharmony_ci while (next < len && got < 4) { 13981cb0ef41Sopenharmony_ci if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) 13991cb0ef41Sopenharmony_ci got++; 14001cb0ef41Sopenharmony_ci else if (buf[next]) 14011cb0ef41Sopenharmony_ci got = 0; 14021cb0ef41Sopenharmony_ci else 14031cb0ef41Sopenharmony_ci got = 4 - got; 14041cb0ef41Sopenharmony_ci next++; 14051cb0ef41Sopenharmony_ci } 14061cb0ef41Sopenharmony_ci *have = got; 14071cb0ef41Sopenharmony_ci return next; 14081cb0ef41Sopenharmony_ci} 14091cb0ef41Sopenharmony_ci 14101cb0ef41Sopenharmony_ciint ZEXPORT inflateSync(z_streamp strm) { 14111cb0ef41Sopenharmony_ci unsigned len; /* number of bytes to look at or looked at */ 14121cb0ef41Sopenharmony_ci int flags; /* temporary to save header status */ 14131cb0ef41Sopenharmony_ci unsigned long in, out; /* temporary to save total_in and total_out */ 14141cb0ef41Sopenharmony_ci unsigned char buf[4]; /* to restore bit buffer to byte string */ 14151cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 14161cb0ef41Sopenharmony_ci 14171cb0ef41Sopenharmony_ci /* check parameters */ 14181cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 14191cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 14201cb0ef41Sopenharmony_ci if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; 14211cb0ef41Sopenharmony_ci 14221cb0ef41Sopenharmony_ci /* if first time, start search in bit buffer */ 14231cb0ef41Sopenharmony_ci if (state->mode != SYNC) { 14241cb0ef41Sopenharmony_ci state->mode = SYNC; 14251cb0ef41Sopenharmony_ci state->hold >>= state->bits & 7; 14261cb0ef41Sopenharmony_ci state->bits -= state->bits & 7; 14271cb0ef41Sopenharmony_ci len = 0; 14281cb0ef41Sopenharmony_ci while (state->bits >= 8) { 14291cb0ef41Sopenharmony_ci buf[len++] = (unsigned char)(state->hold); 14301cb0ef41Sopenharmony_ci state->hold >>= 8; 14311cb0ef41Sopenharmony_ci state->bits -= 8; 14321cb0ef41Sopenharmony_ci } 14331cb0ef41Sopenharmony_ci state->have = 0; 14341cb0ef41Sopenharmony_ci syncsearch(&(state->have), buf, len); 14351cb0ef41Sopenharmony_ci } 14361cb0ef41Sopenharmony_ci 14371cb0ef41Sopenharmony_ci /* search available input */ 14381cb0ef41Sopenharmony_ci len = syncsearch(&(state->have), strm->next_in, strm->avail_in); 14391cb0ef41Sopenharmony_ci strm->avail_in -= len; 14401cb0ef41Sopenharmony_ci strm->next_in += len; 14411cb0ef41Sopenharmony_ci strm->total_in += len; 14421cb0ef41Sopenharmony_ci 14431cb0ef41Sopenharmony_ci /* return no joy or set up to restart inflate() on a new block */ 14441cb0ef41Sopenharmony_ci if (state->have != 4) return Z_DATA_ERROR; 14451cb0ef41Sopenharmony_ci if (state->flags == -1) 14461cb0ef41Sopenharmony_ci state->wrap = 0; /* if no header yet, treat as raw */ 14471cb0ef41Sopenharmony_ci else 14481cb0ef41Sopenharmony_ci state->wrap &= ~4; /* no point in computing a check value now */ 14491cb0ef41Sopenharmony_ci flags = state->flags; 14501cb0ef41Sopenharmony_ci in = strm->total_in; out = strm->total_out; 14511cb0ef41Sopenharmony_ci inflateReset(strm); 14521cb0ef41Sopenharmony_ci strm->total_in = in; strm->total_out = out; 14531cb0ef41Sopenharmony_ci state->flags = flags; 14541cb0ef41Sopenharmony_ci state->mode = TYPE; 14551cb0ef41Sopenharmony_ci return Z_OK; 14561cb0ef41Sopenharmony_ci} 14571cb0ef41Sopenharmony_ci 14581cb0ef41Sopenharmony_ci/* 14591cb0ef41Sopenharmony_ci Returns true if inflate is currently at the end of a block generated by 14601cb0ef41Sopenharmony_ci Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP 14611cb0ef41Sopenharmony_ci implementation to provide an additional safety check. PPP uses 14621cb0ef41Sopenharmony_ci Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored 14631cb0ef41Sopenharmony_ci block. When decompressing, PPP checks that at the end of input packet, 14641cb0ef41Sopenharmony_ci inflate is waiting for these length bytes. 14651cb0ef41Sopenharmony_ci */ 14661cb0ef41Sopenharmony_ciint ZEXPORT inflateSyncPoint(z_streamp strm) { 14671cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 14681cb0ef41Sopenharmony_ci 14691cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 14701cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 14711cb0ef41Sopenharmony_ci return state->mode == STORED && state->bits == 0; 14721cb0ef41Sopenharmony_ci} 14731cb0ef41Sopenharmony_ci 14741cb0ef41Sopenharmony_ciint ZEXPORT inflateCopy(z_streamp dest, z_streamp source) { 14751cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 14761cb0ef41Sopenharmony_ci struct inflate_state FAR *copy; 14771cb0ef41Sopenharmony_ci unsigned char FAR *window; 14781cb0ef41Sopenharmony_ci unsigned wsize; 14791cb0ef41Sopenharmony_ci 14801cb0ef41Sopenharmony_ci /* check input */ 14811cb0ef41Sopenharmony_ci if (inflateStateCheck(source) || dest == Z_NULL) 14821cb0ef41Sopenharmony_ci return Z_STREAM_ERROR; 14831cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)source->state; 14841cb0ef41Sopenharmony_ci 14851cb0ef41Sopenharmony_ci /* allocate space */ 14861cb0ef41Sopenharmony_ci copy = (struct inflate_state FAR *) 14871cb0ef41Sopenharmony_ci ZALLOC(source, 1, sizeof(struct inflate_state)); 14881cb0ef41Sopenharmony_ci if (copy == Z_NULL) return Z_MEM_ERROR; 14891cb0ef41Sopenharmony_ci window = Z_NULL; 14901cb0ef41Sopenharmony_ci if (state->window != Z_NULL) { 14911cb0ef41Sopenharmony_ci window = (unsigned char FAR *)ZALLOC( 14921cb0ef41Sopenharmony_ci source, (1U << state->wbits) + CHUNKCOPY_CHUNK_SIZE, 14931cb0ef41Sopenharmony_ci sizeof(unsigned char)); 14941cb0ef41Sopenharmony_ci if (window == Z_NULL) { 14951cb0ef41Sopenharmony_ci ZFREE(source, copy); 14961cb0ef41Sopenharmony_ci return Z_MEM_ERROR; 14971cb0ef41Sopenharmony_ci } 14981cb0ef41Sopenharmony_ci } 14991cb0ef41Sopenharmony_ci 15001cb0ef41Sopenharmony_ci /* copy state */ 15011cb0ef41Sopenharmony_ci zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); 15021cb0ef41Sopenharmony_ci zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); 15031cb0ef41Sopenharmony_ci copy->strm = dest; 15041cb0ef41Sopenharmony_ci if (state->lencode >= state->codes && 15051cb0ef41Sopenharmony_ci state->lencode <= state->codes + ENOUGH - 1) { 15061cb0ef41Sopenharmony_ci copy->lencode = copy->codes + (state->lencode - state->codes); 15071cb0ef41Sopenharmony_ci copy->distcode = copy->codes + (state->distcode - state->codes); 15081cb0ef41Sopenharmony_ci } 15091cb0ef41Sopenharmony_ci copy->next = copy->codes + (state->next - state->codes); 15101cb0ef41Sopenharmony_ci if (window != Z_NULL) { 15111cb0ef41Sopenharmony_ci wsize = 1U << state->wbits; 15121cb0ef41Sopenharmony_ci zmemcpy(window, state->window, wsize); 15131cb0ef41Sopenharmony_ci } 15141cb0ef41Sopenharmony_ci copy->window = window; 15151cb0ef41Sopenharmony_ci dest->state = (struct internal_state FAR *)copy; 15161cb0ef41Sopenharmony_ci return Z_OK; 15171cb0ef41Sopenharmony_ci} 15181cb0ef41Sopenharmony_ci 15191cb0ef41Sopenharmony_ciint ZEXPORT inflateUndermine(z_streamp strm, int subvert) { 15201cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 15211cb0ef41Sopenharmony_ci 15221cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 15231cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 15241cb0ef41Sopenharmony_ci#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 15251cb0ef41Sopenharmony_ci state->sane = !subvert; 15261cb0ef41Sopenharmony_ci return Z_OK; 15271cb0ef41Sopenharmony_ci#else 15281cb0ef41Sopenharmony_ci (void)subvert; 15291cb0ef41Sopenharmony_ci state->sane = 1; 15301cb0ef41Sopenharmony_ci return Z_DATA_ERROR; 15311cb0ef41Sopenharmony_ci#endif 15321cb0ef41Sopenharmony_ci} 15331cb0ef41Sopenharmony_ci 15341cb0ef41Sopenharmony_ciint ZEXPORT inflateValidate(z_streamp strm, int check) { 15351cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 15361cb0ef41Sopenharmony_ci 15371cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) return Z_STREAM_ERROR; 15381cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 15391cb0ef41Sopenharmony_ci if (check && state->wrap) 15401cb0ef41Sopenharmony_ci state->wrap |= 4; 15411cb0ef41Sopenharmony_ci else 15421cb0ef41Sopenharmony_ci state->wrap &= ~4; 15431cb0ef41Sopenharmony_ci return Z_OK; 15441cb0ef41Sopenharmony_ci} 15451cb0ef41Sopenharmony_ci 15461cb0ef41Sopenharmony_cilong ZEXPORT inflateMark(z_streamp strm) { 15471cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 15481cb0ef41Sopenharmony_ci 15491cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) 15501cb0ef41Sopenharmony_ci return -(1L << 16); 15511cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 15521cb0ef41Sopenharmony_ci return (long)(((unsigned long)((long)state->back)) << 16) + 15531cb0ef41Sopenharmony_ci (state->mode == COPY ? state->length : 15541cb0ef41Sopenharmony_ci (state->mode == MATCH ? state->was - state->length : 0)); 15551cb0ef41Sopenharmony_ci} 15561cb0ef41Sopenharmony_ci 15571cb0ef41Sopenharmony_ciunsigned long ZEXPORT inflateCodesUsed(z_streamp strm) { 15581cb0ef41Sopenharmony_ci struct inflate_state FAR *state; 15591cb0ef41Sopenharmony_ci if (inflateStateCheck(strm)) return (unsigned long)-1; 15601cb0ef41Sopenharmony_ci state = (struct inflate_state FAR *)strm->state; 15611cb0ef41Sopenharmony_ci return (unsigned long)(state->next - state->codes); 15621cb0ef41Sopenharmony_ci} 1563