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