xref: /openbmc/linux/lib/zlib_inflate/inflate.c (revision 9a87ffc99ec8eb8d35eed7c4f816d75f5cc9662e)
14f3865fbSRichard Purdie /* inflate.c -- zlib decompression
24f3865fbSRichard Purdie  * Copyright (C) 1995-2005 Mark Adler
31da177e4SLinus Torvalds  * For conditions of distribution and use, see copyright notice in zlib.h
44f3865fbSRichard Purdie  *
54f3865fbSRichard Purdie  * Based on zlib 1.2.3 but modified for the Linux Kernel by
64f3865fbSRichard Purdie  * Richard Purdie <richard@openedhand.com>
74f3865fbSRichard Purdie  *
84f3865fbSRichard Purdie  * Changes mainly for static instead of dynamic memory allocation
94f3865fbSRichard Purdie  *
101da177e4SLinus Torvalds  */
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds #include <linux/zutil.h>
134f3865fbSRichard Purdie #include "inftrees.h"
144f3865fbSRichard Purdie #include "inflate.h"
154f3865fbSRichard Purdie #include "inffast.h"
161da177e4SLinus Torvalds #include "infutil.h"
171da177e4SLinus Torvalds 
1812619610SMikhail Zaslonko /* architecture-specific bits */
1912619610SMikhail Zaslonko #ifdef CONFIG_ZLIB_DFLTCC
20*9fec9f8eSMikhail Zaslonko #  include "../zlib_dfltcc/dfltcc_inflate.h"
2112619610SMikhail Zaslonko #else
2212619610SMikhail Zaslonko #define INFLATE_RESET_HOOK(strm) do {} while (0)
2312619610SMikhail Zaslonko #define INFLATE_TYPEDO_HOOK(strm, flush) do {} while (0)
2412619610SMikhail Zaslonko #define INFLATE_NEED_UPDATEWINDOW(strm) 1
2512619610SMikhail Zaslonko #define INFLATE_NEED_CHECKSUM(strm) 1
2612619610SMikhail Zaslonko #endif
2712619610SMikhail Zaslonko 
zlib_inflate_workspacesize(void)281da177e4SLinus Torvalds int zlib_inflate_workspacesize(void)
291da177e4SLinus Torvalds {
301da177e4SLinus Torvalds     return sizeof(struct inflate_workspace);
311da177e4SLinus Torvalds }
321da177e4SLinus Torvalds 
zlib_inflateReset(z_streamp strm)334f3865fbSRichard Purdie int zlib_inflateReset(z_streamp strm)
341da177e4SLinus Torvalds {
354f3865fbSRichard Purdie     struct inflate_state *state;
364f3865fbSRichard Purdie 
374f3865fbSRichard Purdie     if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
384f3865fbSRichard Purdie     state = (struct inflate_state *)strm->state;
394f3865fbSRichard Purdie     strm->total_in = strm->total_out = state->total = 0;
404f3865fbSRichard Purdie     strm->msg = NULL;
414f3865fbSRichard Purdie     strm->adler = 1;        /* to support ill-conceived Java test suite */
424f3865fbSRichard Purdie     state->mode = HEAD;
434f3865fbSRichard Purdie     state->last = 0;
444f3865fbSRichard Purdie     state->havedict = 0;
454f3865fbSRichard Purdie     state->dmax = 32768U;
464f3865fbSRichard Purdie     state->hold = 0;
474f3865fbSRichard Purdie     state->bits = 0;
484f3865fbSRichard Purdie     state->lencode = state->distcode = state->next = state->codes;
494f3865fbSRichard Purdie 
504f3865fbSRichard Purdie     /* Initialise Window */
514f3865fbSRichard Purdie     state->wsize = 1U << state->wbits;
524f3865fbSRichard Purdie     state->write = 0;
534f3865fbSRichard Purdie     state->whave = 0;
544f3865fbSRichard Purdie 
5512619610SMikhail Zaslonko     INFLATE_RESET_HOOK(strm);
561da177e4SLinus Torvalds     return Z_OK;
571da177e4SLinus Torvalds }
581da177e4SLinus Torvalds 
zlib_inflateInit2(z_streamp strm,int windowBits)594f3865fbSRichard Purdie int zlib_inflateInit2(z_streamp strm, int windowBits)
601da177e4SLinus Torvalds {
614f3865fbSRichard Purdie     struct inflate_state *state;
621da177e4SLinus Torvalds 
634f3865fbSRichard Purdie     if (strm == NULL) return Z_STREAM_ERROR;
644f3865fbSRichard Purdie     strm->msg = NULL;                 /* in case we return an error */
651da177e4SLinus Torvalds 
664f3865fbSRichard Purdie     state = &WS(strm)->inflate_state;
674f3865fbSRichard Purdie     strm->state = (struct internal_state *)state;
684f3865fbSRichard Purdie 
694f3865fbSRichard Purdie     if (windowBits < 0) {
704f3865fbSRichard Purdie         state->wrap = 0;
714f3865fbSRichard Purdie         windowBits = -windowBits;
721da177e4SLinus Torvalds     }
734f3865fbSRichard Purdie     else {
744f3865fbSRichard Purdie         state->wrap = (windowBits >> 4) + 1;
754f3865fbSRichard Purdie     }
764f3865fbSRichard Purdie     if (windowBits < 8 || windowBits > 15) {
771da177e4SLinus Torvalds         return Z_STREAM_ERROR;
781da177e4SLinus Torvalds     }
794f3865fbSRichard Purdie     state->wbits = (unsigned)windowBits;
8012619610SMikhail Zaslonko #ifdef CONFIG_ZLIB_DFLTCC
8112619610SMikhail Zaslonko     /*
8212619610SMikhail Zaslonko      * DFLTCC requires the window to be page aligned.
8312619610SMikhail Zaslonko      * Thus, we overallocate and take the aligned portion of the buffer.
8412619610SMikhail Zaslonko      */
8512619610SMikhail Zaslonko     state->window = PTR_ALIGN(&WS(strm)->working_window[0], PAGE_SIZE);
8612619610SMikhail Zaslonko #else
874f3865fbSRichard Purdie     state->window = &WS(strm)->working_window[0];
8812619610SMikhail Zaslonko #endif
891da177e4SLinus Torvalds 
904f3865fbSRichard Purdie     return zlib_inflateReset(strm);
911da177e4SLinus Torvalds }
921da177e4SLinus Torvalds 
934f3865fbSRichard Purdie /*
944f3865fbSRichard Purdie    Return state with length and distance decoding tables and index sizes set to
954f3865fbSRichard Purdie    fixed code decoding.  This returns fixed tables from inffixed.h.
964f3865fbSRichard Purdie  */
zlib_fixedtables(struct inflate_state * state)974f3865fbSRichard Purdie static void zlib_fixedtables(struct inflate_state *state)
984f3865fbSRichard Purdie {
994f3865fbSRichard Purdie #   include "inffixed.h"
1004f3865fbSRichard Purdie     state->lencode = lenfix;
1014f3865fbSRichard Purdie     state->lenbits = 9;
1024f3865fbSRichard Purdie     state->distcode = distfix;
1034f3865fbSRichard Purdie     state->distbits = 5;
1044f3865fbSRichard Purdie }
1054f3865fbSRichard Purdie 
1064f3865fbSRichard Purdie 
1074f3865fbSRichard Purdie /*
1084f3865fbSRichard Purdie    Update the window with the last wsize (normally 32K) bytes written before
1094f3865fbSRichard Purdie    returning. This is only called when a window is already in use, or when
1104f3865fbSRichard Purdie    output has been written during this inflate call, but the end of the deflate
1114f3865fbSRichard Purdie    stream has not been reached yet. It is also called to window dictionary data
1124f3865fbSRichard Purdie    when a dictionary is loaded.
1134f3865fbSRichard Purdie 
1144f3865fbSRichard Purdie    Providing output buffers larger than 32K to inflate() should provide a speed
1154f3865fbSRichard Purdie    advantage, since only the last 32K of output is copied to the sliding window
1164f3865fbSRichard Purdie    upon return from inflate(), and since all distances after the first 32K of
1174f3865fbSRichard Purdie    output will fall in the output data, making match copies simpler and faster.
1184f3865fbSRichard Purdie    The advantage may be dependent on the size of the processor's data caches.
1194f3865fbSRichard Purdie  */
zlib_updatewindow(z_streamp strm,unsigned out)1204f3865fbSRichard Purdie static void zlib_updatewindow(z_streamp strm, unsigned out)
1214f3865fbSRichard Purdie {
1224f3865fbSRichard Purdie     struct inflate_state *state;
1234f3865fbSRichard Purdie     unsigned copy, dist;
1244f3865fbSRichard Purdie 
1254f3865fbSRichard Purdie     state = (struct inflate_state *)strm->state;
1264f3865fbSRichard Purdie 
1274f3865fbSRichard Purdie     /* copy state->wsize or less output bytes into the circular window */
1284f3865fbSRichard Purdie     copy = out - strm->avail_out;
1294f3865fbSRichard Purdie     if (copy >= state->wsize) {
1304f3865fbSRichard Purdie         memcpy(state->window, strm->next_out - state->wsize, state->wsize);
1314f3865fbSRichard Purdie         state->write = 0;
1324f3865fbSRichard Purdie         state->whave = state->wsize;
1334f3865fbSRichard Purdie     }
1344f3865fbSRichard Purdie     else {
1354f3865fbSRichard Purdie         dist = state->wsize - state->write;
1364f3865fbSRichard Purdie         if (dist > copy) dist = copy;
1374f3865fbSRichard Purdie         memcpy(state->window + state->write, strm->next_out - copy, dist);
1384f3865fbSRichard Purdie         copy -= dist;
1394f3865fbSRichard Purdie         if (copy) {
1404f3865fbSRichard Purdie             memcpy(state->window, strm->next_out - copy, copy);
1414f3865fbSRichard Purdie             state->write = copy;
1424f3865fbSRichard Purdie             state->whave = state->wsize;
1434f3865fbSRichard Purdie         }
1444f3865fbSRichard Purdie         else {
1454f3865fbSRichard Purdie             state->write += dist;
1464f3865fbSRichard Purdie             if (state->write == state->wsize) state->write = 0;
1474f3865fbSRichard Purdie             if (state->whave < state->wsize) state->whave += dist;
1484f3865fbSRichard Purdie         }
1494f3865fbSRichard Purdie     }
1501da177e4SLinus Torvalds }
1511da177e4SLinus Torvalds 
1521da177e4SLinus Torvalds 
1531da177e4SLinus Torvalds /*
1541da177e4SLinus Torvalds  * At the end of a Deflate-compressed PPP packet, we expect to have seen
1551da177e4SLinus Torvalds  * a `stored' block type value but not the (zero) length bytes.
1561da177e4SLinus Torvalds  */
1574f3865fbSRichard Purdie /*
1584f3865fbSRichard Purdie    Returns true if inflate is currently at the end of a block generated by
1594f3865fbSRichard Purdie    Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
1604f3865fbSRichard Purdie    implementation to provide an additional safety check. PPP uses
1614f3865fbSRichard Purdie    Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
1624f3865fbSRichard Purdie    block. When decompressing, PPP checks that at the end of input packet,
1634f3865fbSRichard Purdie    inflate is waiting for these length bytes.
1644f3865fbSRichard Purdie  */
zlib_inflateSyncPacket(z_streamp strm)1654f3865fbSRichard Purdie static int zlib_inflateSyncPacket(z_streamp strm)
1661da177e4SLinus Torvalds {
1674f3865fbSRichard Purdie     struct inflate_state *state;
1684f3865fbSRichard Purdie 
1694f3865fbSRichard Purdie     if (strm == NULL || strm->state == NULL) return Z_STREAM_ERROR;
1704f3865fbSRichard Purdie     state = (struct inflate_state *)strm->state;
1714f3865fbSRichard Purdie 
1724f3865fbSRichard Purdie     if (state->mode == STORED && state->bits == 0) {
1734f3865fbSRichard Purdie 	state->mode = TYPE;
1741da177e4SLinus Torvalds         return Z_OK;
1751da177e4SLinus Torvalds     }
1761da177e4SLinus Torvalds     return Z_DATA_ERROR;
1774f3865fbSRichard Purdie }
1784f3865fbSRichard Purdie 
1794f3865fbSRichard Purdie /* Macros for inflate(): */
1804f3865fbSRichard Purdie 
1814f3865fbSRichard Purdie /* check function to use adler32() for zlib or crc32() for gzip */
1824f3865fbSRichard Purdie #define UPDATE(check, buf, len) zlib_adler32(check, buf, len)
1834f3865fbSRichard Purdie 
1844f3865fbSRichard Purdie /* Load registers with state in inflate() for speed */
1854f3865fbSRichard Purdie #define LOAD() \
1864f3865fbSRichard Purdie     do { \
1874f3865fbSRichard Purdie         put = strm->next_out; \
1884f3865fbSRichard Purdie         left = strm->avail_out; \
1894f3865fbSRichard Purdie         next = strm->next_in; \
1904f3865fbSRichard Purdie         have = strm->avail_in; \
1914f3865fbSRichard Purdie         hold = state->hold; \
1924f3865fbSRichard Purdie         bits = state->bits; \
1934f3865fbSRichard Purdie     } while (0)
1944f3865fbSRichard Purdie 
1954f3865fbSRichard Purdie /* Restore state from registers in inflate() */
1964f3865fbSRichard Purdie #define RESTORE() \
1974f3865fbSRichard Purdie     do { \
1984f3865fbSRichard Purdie         strm->next_out = put; \
1994f3865fbSRichard Purdie         strm->avail_out = left; \
2004f3865fbSRichard Purdie         strm->next_in = next; \
2014f3865fbSRichard Purdie         strm->avail_in = have; \
2024f3865fbSRichard Purdie         state->hold = hold; \
2034f3865fbSRichard Purdie         state->bits = bits; \
2044f3865fbSRichard Purdie     } while (0)
2054f3865fbSRichard Purdie 
2064f3865fbSRichard Purdie /* Clear the input bit accumulator */
2074f3865fbSRichard Purdie #define INITBITS() \
2084f3865fbSRichard Purdie     do { \
2094f3865fbSRichard Purdie         hold = 0; \
2104f3865fbSRichard Purdie         bits = 0; \
2114f3865fbSRichard Purdie     } while (0)
2124f3865fbSRichard Purdie 
2134f3865fbSRichard Purdie /* Get a byte of input into the bit accumulator, or return from inflate()
2144f3865fbSRichard Purdie    if there is no input available. */
2154f3865fbSRichard Purdie #define PULLBYTE() \
2164f3865fbSRichard Purdie     do { \
2174f3865fbSRichard Purdie         if (have == 0) goto inf_leave; \
2184f3865fbSRichard Purdie         have--; \
2194f3865fbSRichard Purdie         hold += (unsigned long)(*next++) << bits; \
2204f3865fbSRichard Purdie         bits += 8; \
2214f3865fbSRichard Purdie     } while (0)
2224f3865fbSRichard Purdie 
2234f3865fbSRichard Purdie /* Assure that there are at least n bits in the bit accumulator.  If there is
2244f3865fbSRichard Purdie    not enough available input to do that, then return from inflate(). */
2254f3865fbSRichard Purdie #define NEEDBITS(n) \
2264f3865fbSRichard Purdie     do { \
2274f3865fbSRichard Purdie         while (bits < (unsigned)(n)) \
2284f3865fbSRichard Purdie             PULLBYTE(); \
2294f3865fbSRichard Purdie     } while (0)
2304f3865fbSRichard Purdie 
2314f3865fbSRichard Purdie /* Return the low n bits of the bit accumulator (n < 16) */
2324f3865fbSRichard Purdie #define BITS(n) \
2334f3865fbSRichard Purdie     ((unsigned)hold & ((1U << (n)) - 1))
2344f3865fbSRichard Purdie 
2354f3865fbSRichard Purdie /* Remove n bits from the bit accumulator */
2364f3865fbSRichard Purdie #define DROPBITS(n) \
2374f3865fbSRichard Purdie     do { \
2384f3865fbSRichard Purdie         hold >>= (n); \
2394f3865fbSRichard Purdie         bits -= (unsigned)(n); \
2404f3865fbSRichard Purdie     } while (0)
2414f3865fbSRichard Purdie 
2424f3865fbSRichard Purdie /* Remove zero to seven bits as needed to go to a byte boundary */
2434f3865fbSRichard Purdie #define BYTEBITS() \
2444f3865fbSRichard Purdie     do { \
2454f3865fbSRichard Purdie         hold >>= bits & 7; \
2464f3865fbSRichard Purdie         bits -= bits & 7; \
2474f3865fbSRichard Purdie     } while (0)
2484f3865fbSRichard Purdie 
2494f3865fbSRichard Purdie /*
2504f3865fbSRichard Purdie    inflate() uses a state machine to process as much input data and generate as
2514f3865fbSRichard Purdie    much output data as possible before returning.  The state machine is
2524f3865fbSRichard Purdie    structured roughly as follows:
2534f3865fbSRichard Purdie 
2544f3865fbSRichard Purdie     for (;;) switch (state) {
2554f3865fbSRichard Purdie     ...
2564f3865fbSRichard Purdie     case STATEn:
2574f3865fbSRichard Purdie         if (not enough input data or output space to make progress)
2584f3865fbSRichard Purdie             return;
2594f3865fbSRichard Purdie         ... make progress ...
2604f3865fbSRichard Purdie         state = STATEm;
2614f3865fbSRichard Purdie         break;
2624f3865fbSRichard Purdie     ...
2634f3865fbSRichard Purdie     }
2644f3865fbSRichard Purdie 
2654f3865fbSRichard Purdie    so when inflate() is called again, the same case is attempted again, and
2664f3865fbSRichard Purdie    if the appropriate resources are provided, the machine proceeds to the
2674f3865fbSRichard Purdie    next state.  The NEEDBITS() macro is usually the way the state evaluates
2684f3865fbSRichard Purdie    whether it can proceed or should return.  NEEDBITS() does the return if
2694f3865fbSRichard Purdie    the requested bits are not available.  The typical use of the BITS macros
2704f3865fbSRichard Purdie    is:
2714f3865fbSRichard Purdie 
2724f3865fbSRichard Purdie         NEEDBITS(n);
2734f3865fbSRichard Purdie         ... do something with BITS(n) ...
2744f3865fbSRichard Purdie         DROPBITS(n);
2754f3865fbSRichard Purdie 
2764f3865fbSRichard Purdie    where NEEDBITS(n) either returns from inflate() if there isn't enough
2774f3865fbSRichard Purdie    input left to load n bits into the accumulator, or it continues.  BITS(n)
2784f3865fbSRichard Purdie    gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
2794f3865fbSRichard Purdie    the low n bits off the accumulator.  INITBITS() clears the accumulator
2804f3865fbSRichard Purdie    and sets the number of available bits to zero.  BYTEBITS() discards just
2814f3865fbSRichard Purdie    enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
2824f3865fbSRichard Purdie    and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
2834f3865fbSRichard Purdie 
2844f3865fbSRichard Purdie    NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
2854f3865fbSRichard Purdie    if there is no input available.  The decoding of variable length codes uses
2864f3865fbSRichard Purdie    PULLBYTE() directly in order to pull just enough bytes to decode the next
2874f3865fbSRichard Purdie    code, and no more.
2884f3865fbSRichard Purdie 
2894f3865fbSRichard Purdie    Some states loop until they get enough input, making sure that enough
2904f3865fbSRichard Purdie    state information is maintained to continue the loop where it left off
2914f3865fbSRichard Purdie    if NEEDBITS() returns in the loop.  For example, want, need, and keep
2924f3865fbSRichard Purdie    would all have to actually be part of the saved state in case NEEDBITS()
2934f3865fbSRichard Purdie    returns:
2944f3865fbSRichard Purdie 
2954f3865fbSRichard Purdie     case STATEw:
2964f3865fbSRichard Purdie         while (want < need) {
2974f3865fbSRichard Purdie             NEEDBITS(n);
2984f3865fbSRichard Purdie             keep[want++] = BITS(n);
2994f3865fbSRichard Purdie             DROPBITS(n);
3004f3865fbSRichard Purdie         }
3014f3865fbSRichard Purdie         state = STATEx;
3024f3865fbSRichard Purdie     case STATEx:
3034f3865fbSRichard Purdie 
3044f3865fbSRichard Purdie    As shown above, if the next state is also the next case, then the break
3054f3865fbSRichard Purdie    is omitted.
3064f3865fbSRichard Purdie 
3074f3865fbSRichard Purdie    A state may also return if there is not enough output space available to
3084f3865fbSRichard Purdie    complete that state.  Those states are copying stored data, writing a
3094f3865fbSRichard Purdie    literal byte, and copying a matching string.
3104f3865fbSRichard Purdie 
3114f3865fbSRichard Purdie    When returning, a "goto inf_leave" is used to update the total counters,
3124f3865fbSRichard Purdie    update the check value, and determine whether any progress has been made
3134f3865fbSRichard Purdie    during that inflate() call in order to return the proper return code.
3144f3865fbSRichard Purdie    Progress is defined as a change in either strm->avail_in or strm->avail_out.
3154f3865fbSRichard Purdie    When there is a window, goto inf_leave will update the window with the last
3164f3865fbSRichard Purdie    output written.  If a goto inf_leave occurs in the middle of decompression
3174f3865fbSRichard Purdie    and there is no window currently, goto inf_leave will create one and copy
3184f3865fbSRichard Purdie    output to the window for the next call of inflate().
3194f3865fbSRichard Purdie 
3204f3865fbSRichard Purdie    In this implementation, the flush parameter of inflate() only affects the
3214f3865fbSRichard Purdie    return code (per zlib.h).  inflate() always writes as much as possible to
3224f3865fbSRichard Purdie    strm->next_out, given the space available and the provided input--the effect
3234f3865fbSRichard Purdie    documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
3244f3865fbSRichard Purdie    the allocation of and copying into a sliding window until necessary, which
3254f3865fbSRichard Purdie    provides the effect documented in zlib.h for Z_FINISH when the entire input
3264f3865fbSRichard Purdie    stream available.  So the only thing the flush parameter actually does is:
3274f3865fbSRichard Purdie    when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
3284f3865fbSRichard Purdie    will return Z_BUF_ERROR if it has not reached the end of the stream.
3294f3865fbSRichard Purdie  */
3304f3865fbSRichard Purdie 
zlib_inflate(z_streamp strm,int flush)3314f3865fbSRichard Purdie int zlib_inflate(z_streamp strm, int flush)
3324f3865fbSRichard Purdie {
3334f3865fbSRichard Purdie     struct inflate_state *state;
3348336793bSDenys Vlasenko     const unsigned char *next;  /* next input */
3354f3865fbSRichard Purdie     unsigned char *put;         /* next output */
3364f3865fbSRichard Purdie     unsigned have, left;        /* available input and output */
3374f3865fbSRichard Purdie     unsigned long hold;         /* bit buffer */
3384f3865fbSRichard Purdie     unsigned bits;              /* bits in bit buffer */
3394f3865fbSRichard Purdie     unsigned in, out;           /* save starting available input and output */
3404f3865fbSRichard Purdie     unsigned copy;              /* number of stored or match bytes to copy */
3414f3865fbSRichard Purdie     unsigned char *from;        /* where to copy match bytes from */
3424f3865fbSRichard Purdie     code this;                  /* current decoding table entry */
3434f3865fbSRichard Purdie     code last;                  /* parent table entry */
3444f3865fbSRichard Purdie     unsigned len;               /* length to copy for repeats, bits to drop */
3454f3865fbSRichard Purdie     int ret;                    /* return code */
3464f3865fbSRichard Purdie     static const unsigned short order[19] = /* permutation of code lengths */
3474f3865fbSRichard Purdie         {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
3484f3865fbSRichard Purdie 
34931925c88SPeter Korsgaard     /* Do not check for strm->next_out == NULL here as ppc zImage
35031925c88SPeter Korsgaard        inflates to strm->next_out = 0 */
35131925c88SPeter Korsgaard 
35231925c88SPeter Korsgaard     if (strm == NULL || strm->state == NULL ||
3534f3865fbSRichard Purdie         (strm->next_in == NULL && strm->avail_in != 0))
3544f3865fbSRichard Purdie         return Z_STREAM_ERROR;
3554f3865fbSRichard Purdie 
3564f3865fbSRichard Purdie     state = (struct inflate_state *)strm->state;
3574f3865fbSRichard Purdie 
3584f3865fbSRichard Purdie     if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
3594f3865fbSRichard Purdie     LOAD();
3604f3865fbSRichard Purdie     in = have;
3614f3865fbSRichard Purdie     out = left;
3624f3865fbSRichard Purdie     ret = Z_OK;
3634f3865fbSRichard Purdie     for (;;)
3644f3865fbSRichard Purdie         switch (state->mode) {
3654f3865fbSRichard Purdie         case HEAD:
3664f3865fbSRichard Purdie             if (state->wrap == 0) {
3674f3865fbSRichard Purdie                 state->mode = TYPEDO;
3684f3865fbSRichard Purdie                 break;
3694f3865fbSRichard Purdie             }
3704f3865fbSRichard Purdie             NEEDBITS(16);
3714f3865fbSRichard Purdie             if (
3724f3865fbSRichard Purdie                 ((BITS(8) << 8) + (hold >> 8)) % 31) {
3734f3865fbSRichard Purdie                 strm->msg = (char *)"incorrect header check";
3744f3865fbSRichard Purdie                 state->mode = BAD;
3754f3865fbSRichard Purdie                 break;
3764f3865fbSRichard Purdie             }
3774f3865fbSRichard Purdie             if (BITS(4) != Z_DEFLATED) {
3784f3865fbSRichard Purdie                 strm->msg = (char *)"unknown compression method";
3794f3865fbSRichard Purdie                 state->mode = BAD;
3804f3865fbSRichard Purdie                 break;
3814f3865fbSRichard Purdie             }
3824f3865fbSRichard Purdie             DROPBITS(4);
3834f3865fbSRichard Purdie             len = BITS(4) + 8;
3844f3865fbSRichard Purdie             if (len > state->wbits) {
3854f3865fbSRichard Purdie                 strm->msg = (char *)"invalid window size";
3864f3865fbSRichard Purdie                 state->mode = BAD;
3874f3865fbSRichard Purdie                 break;
3884f3865fbSRichard Purdie             }
3894f3865fbSRichard Purdie             state->dmax = 1U << len;
3904f3865fbSRichard Purdie             strm->adler = state->check = zlib_adler32(0L, NULL, 0);
3914f3865fbSRichard Purdie             state->mode = hold & 0x200 ? DICTID : TYPE;
3924f3865fbSRichard Purdie             INITBITS();
3934f3865fbSRichard Purdie             break;
3944f3865fbSRichard Purdie         case DICTID:
3954f3865fbSRichard Purdie             NEEDBITS(32);
3964f3865fbSRichard Purdie             strm->adler = state->check = REVERSE(hold);
3974f3865fbSRichard Purdie             INITBITS();
3984f3865fbSRichard Purdie             state->mode = DICT;
39936f9ff9eSGustavo A. R. Silva 	    fallthrough;
4004f3865fbSRichard Purdie         case DICT:
4014f3865fbSRichard Purdie             if (state->havedict == 0) {
4024f3865fbSRichard Purdie                 RESTORE();
4034f3865fbSRichard Purdie                 return Z_NEED_DICT;
4044f3865fbSRichard Purdie             }
4054f3865fbSRichard Purdie             strm->adler = state->check = zlib_adler32(0L, NULL, 0);
4064f3865fbSRichard Purdie             state->mode = TYPE;
40736f9ff9eSGustavo A. R. Silva 	    fallthrough;
4084f3865fbSRichard Purdie         case TYPE:
4094f3865fbSRichard Purdie             if (flush == Z_BLOCK) goto inf_leave;
41036f9ff9eSGustavo A. R. Silva 	    fallthrough;
4114f3865fbSRichard Purdie         case TYPEDO:
41212619610SMikhail Zaslonko             INFLATE_TYPEDO_HOOK(strm, flush);
4134f3865fbSRichard Purdie             if (state->last) {
4144f3865fbSRichard Purdie                 BYTEBITS();
4154f3865fbSRichard Purdie                 state->mode = CHECK;
4164f3865fbSRichard Purdie                 break;
4174f3865fbSRichard Purdie             }
4184f3865fbSRichard Purdie             NEEDBITS(3);
4194f3865fbSRichard Purdie             state->last = BITS(1);
4204f3865fbSRichard Purdie             DROPBITS(1);
4214f3865fbSRichard Purdie             switch (BITS(2)) {
4224f3865fbSRichard Purdie             case 0:                             /* stored block */
4234f3865fbSRichard Purdie                 state->mode = STORED;
4244f3865fbSRichard Purdie                 break;
4254f3865fbSRichard Purdie             case 1:                             /* fixed block */
4264f3865fbSRichard Purdie                 zlib_fixedtables(state);
4274f3865fbSRichard Purdie                 state->mode = LEN;              /* decode codes */
4284f3865fbSRichard Purdie                 break;
4294f3865fbSRichard Purdie             case 2:                             /* dynamic block */
4304f3865fbSRichard Purdie                 state->mode = TABLE;
4314f3865fbSRichard Purdie                 break;
4324f3865fbSRichard Purdie             case 3:
4334f3865fbSRichard Purdie                 strm->msg = (char *)"invalid block type";
4344f3865fbSRichard Purdie                 state->mode = BAD;
4354f3865fbSRichard Purdie             }
4364f3865fbSRichard Purdie             DROPBITS(2);
4374f3865fbSRichard Purdie             break;
4384f3865fbSRichard Purdie         case STORED:
4394f3865fbSRichard Purdie             BYTEBITS();                         /* go to byte boundary */
4404f3865fbSRichard Purdie             NEEDBITS(32);
4414f3865fbSRichard Purdie             if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
4424f3865fbSRichard Purdie                 strm->msg = (char *)"invalid stored block lengths";
4434f3865fbSRichard Purdie                 state->mode = BAD;
4444f3865fbSRichard Purdie                 break;
4454f3865fbSRichard Purdie             }
4464f3865fbSRichard Purdie             state->length = (unsigned)hold & 0xffff;
4474f3865fbSRichard Purdie             INITBITS();
4484f3865fbSRichard Purdie             state->mode = COPY;
44936f9ff9eSGustavo A. R. Silva 	    fallthrough;
4504f3865fbSRichard Purdie         case COPY:
4514f3865fbSRichard Purdie             copy = state->length;
4524f3865fbSRichard Purdie             if (copy) {
4534f3865fbSRichard Purdie                 if (copy > have) copy = have;
4544f3865fbSRichard Purdie                 if (copy > left) copy = left;
4554f3865fbSRichard Purdie                 if (copy == 0) goto inf_leave;
4564f3865fbSRichard Purdie                 memcpy(put, next, copy);
4574f3865fbSRichard Purdie                 have -= copy;
4584f3865fbSRichard Purdie                 next += copy;
4594f3865fbSRichard Purdie                 left -= copy;
4604f3865fbSRichard Purdie                 put += copy;
4614f3865fbSRichard Purdie                 state->length -= copy;
4624f3865fbSRichard Purdie                 break;
4634f3865fbSRichard Purdie             }
4644f3865fbSRichard Purdie             state->mode = TYPE;
4654f3865fbSRichard Purdie             break;
4664f3865fbSRichard Purdie         case TABLE:
4674f3865fbSRichard Purdie             NEEDBITS(14);
4684f3865fbSRichard Purdie             state->nlen = BITS(5) + 257;
4694f3865fbSRichard Purdie             DROPBITS(5);
4704f3865fbSRichard Purdie             state->ndist = BITS(5) + 1;
4714f3865fbSRichard Purdie             DROPBITS(5);
4724f3865fbSRichard Purdie             state->ncode = BITS(4) + 4;
4734f3865fbSRichard Purdie             DROPBITS(4);
4744f3865fbSRichard Purdie #ifndef PKZIP_BUG_WORKAROUND
4754f3865fbSRichard Purdie             if (state->nlen > 286 || state->ndist > 30) {
4764f3865fbSRichard Purdie                 strm->msg = (char *)"too many length or distance symbols";
4774f3865fbSRichard Purdie                 state->mode = BAD;
4784f3865fbSRichard Purdie                 break;
4794f3865fbSRichard Purdie             }
4804f3865fbSRichard Purdie #endif
4814f3865fbSRichard Purdie             state->have = 0;
4824f3865fbSRichard Purdie             state->mode = LENLENS;
48336f9ff9eSGustavo A. R. Silva 	    fallthrough;
4844f3865fbSRichard Purdie         case LENLENS:
4854f3865fbSRichard Purdie             while (state->have < state->ncode) {
4864f3865fbSRichard Purdie                 NEEDBITS(3);
4874f3865fbSRichard Purdie                 state->lens[order[state->have++]] = (unsigned short)BITS(3);
4884f3865fbSRichard Purdie                 DROPBITS(3);
4894f3865fbSRichard Purdie             }
4904f3865fbSRichard Purdie             while (state->have < 19)
4914f3865fbSRichard Purdie                 state->lens[order[state->have++]] = 0;
4924f3865fbSRichard Purdie             state->next = state->codes;
4934f3865fbSRichard Purdie             state->lencode = (code const *)(state->next);
4944f3865fbSRichard Purdie             state->lenbits = 7;
4954f3865fbSRichard Purdie             ret = zlib_inflate_table(CODES, state->lens, 19, &(state->next),
4964f3865fbSRichard Purdie                                 &(state->lenbits), state->work);
4974f3865fbSRichard Purdie             if (ret) {
4984f3865fbSRichard Purdie                 strm->msg = (char *)"invalid code lengths set";
4994f3865fbSRichard Purdie                 state->mode = BAD;
5004f3865fbSRichard Purdie                 break;
5014f3865fbSRichard Purdie             }
5024f3865fbSRichard Purdie             state->have = 0;
5034f3865fbSRichard Purdie             state->mode = CODELENS;
50436f9ff9eSGustavo A. R. Silva 	    fallthrough;
5054f3865fbSRichard Purdie         case CODELENS:
5064f3865fbSRichard Purdie             while (state->have < state->nlen + state->ndist) {
5074f3865fbSRichard Purdie                 for (;;) {
5084f3865fbSRichard Purdie                     this = state->lencode[BITS(state->lenbits)];
5094f3865fbSRichard Purdie                     if ((unsigned)(this.bits) <= bits) break;
5104f3865fbSRichard Purdie                     PULLBYTE();
5114f3865fbSRichard Purdie                 }
5124f3865fbSRichard Purdie                 if (this.val < 16) {
5134f3865fbSRichard Purdie                     NEEDBITS(this.bits);
5144f3865fbSRichard Purdie                     DROPBITS(this.bits);
5154f3865fbSRichard Purdie                     state->lens[state->have++] = this.val;
5164f3865fbSRichard Purdie                 }
5174f3865fbSRichard Purdie                 else {
5184f3865fbSRichard Purdie                     if (this.val == 16) {
5194f3865fbSRichard Purdie                         NEEDBITS(this.bits + 2);
5204f3865fbSRichard Purdie                         DROPBITS(this.bits);
5214f3865fbSRichard Purdie                         if (state->have == 0) {
5224f3865fbSRichard Purdie                             strm->msg = (char *)"invalid bit length repeat";
5234f3865fbSRichard Purdie                             state->mode = BAD;
5244f3865fbSRichard Purdie                             break;
5254f3865fbSRichard Purdie                         }
5264f3865fbSRichard Purdie                         len = state->lens[state->have - 1];
5274f3865fbSRichard Purdie                         copy = 3 + BITS(2);
5284f3865fbSRichard Purdie                         DROPBITS(2);
5294f3865fbSRichard Purdie                     }
5304f3865fbSRichard Purdie                     else if (this.val == 17) {
5314f3865fbSRichard Purdie                         NEEDBITS(this.bits + 3);
5324f3865fbSRichard Purdie                         DROPBITS(this.bits);
5334f3865fbSRichard Purdie                         len = 0;
5344f3865fbSRichard Purdie                         copy = 3 + BITS(3);
5354f3865fbSRichard Purdie                         DROPBITS(3);
5364f3865fbSRichard Purdie                     }
5374f3865fbSRichard Purdie                     else {
5384f3865fbSRichard Purdie                         NEEDBITS(this.bits + 7);
5394f3865fbSRichard Purdie                         DROPBITS(this.bits);
5404f3865fbSRichard Purdie                         len = 0;
5414f3865fbSRichard Purdie                         copy = 11 + BITS(7);
5424f3865fbSRichard Purdie                         DROPBITS(7);
5434f3865fbSRichard Purdie                     }
5444f3865fbSRichard Purdie                     if (state->have + copy > state->nlen + state->ndist) {
5454f3865fbSRichard Purdie                         strm->msg = (char *)"invalid bit length repeat";
5464f3865fbSRichard Purdie                         state->mode = BAD;
5474f3865fbSRichard Purdie                         break;
5484f3865fbSRichard Purdie                     }
5494f3865fbSRichard Purdie                     while (copy--)
5504f3865fbSRichard Purdie                         state->lens[state->have++] = (unsigned short)len;
5514f3865fbSRichard Purdie                 }
5524f3865fbSRichard Purdie             }
5534f3865fbSRichard Purdie 
5544f3865fbSRichard Purdie             /* handle error breaks in while */
5554f3865fbSRichard Purdie             if (state->mode == BAD) break;
5564f3865fbSRichard Purdie 
5574f3865fbSRichard Purdie             /* build code tables */
5584f3865fbSRichard Purdie             state->next = state->codes;
5594f3865fbSRichard Purdie             state->lencode = (code const *)(state->next);
5604f3865fbSRichard Purdie             state->lenbits = 9;
5614f3865fbSRichard Purdie             ret = zlib_inflate_table(LENS, state->lens, state->nlen, &(state->next),
5624f3865fbSRichard Purdie                                 &(state->lenbits), state->work);
5634f3865fbSRichard Purdie             if (ret) {
5644f3865fbSRichard Purdie                 strm->msg = (char *)"invalid literal/lengths set";
5654f3865fbSRichard Purdie                 state->mode = BAD;
5664f3865fbSRichard Purdie                 break;
5674f3865fbSRichard Purdie             }
5684f3865fbSRichard Purdie             state->distcode = (code const *)(state->next);
5694f3865fbSRichard Purdie             state->distbits = 6;
5704f3865fbSRichard Purdie             ret = zlib_inflate_table(DISTS, state->lens + state->nlen, state->ndist,
5714f3865fbSRichard Purdie                             &(state->next), &(state->distbits), state->work);
5724f3865fbSRichard Purdie             if (ret) {
5734f3865fbSRichard Purdie                 strm->msg = (char *)"invalid distances set";
5744f3865fbSRichard Purdie                 state->mode = BAD;
5754f3865fbSRichard Purdie                 break;
5764f3865fbSRichard Purdie             }
5774f3865fbSRichard Purdie             state->mode = LEN;
57836f9ff9eSGustavo A. R. Silva 	    fallthrough;
5794f3865fbSRichard Purdie         case LEN:
5804f3865fbSRichard Purdie             if (have >= 6 && left >= 258) {
5814f3865fbSRichard Purdie                 RESTORE();
5824f3865fbSRichard Purdie                 inflate_fast(strm, out);
5834f3865fbSRichard Purdie                 LOAD();
5844f3865fbSRichard Purdie                 break;
5854f3865fbSRichard Purdie             }
5864f3865fbSRichard Purdie             for (;;) {
5874f3865fbSRichard Purdie                 this = state->lencode[BITS(state->lenbits)];
5884f3865fbSRichard Purdie                 if ((unsigned)(this.bits) <= bits) break;
5894f3865fbSRichard Purdie                 PULLBYTE();
5904f3865fbSRichard Purdie             }
5914f3865fbSRichard Purdie             if (this.op && (this.op & 0xf0) == 0) {
5924f3865fbSRichard Purdie                 last = this;
5934f3865fbSRichard Purdie                 for (;;) {
5944f3865fbSRichard Purdie                     this = state->lencode[last.val +
5954f3865fbSRichard Purdie                             (BITS(last.bits + last.op) >> last.bits)];
5964f3865fbSRichard Purdie                     if ((unsigned)(last.bits + this.bits) <= bits) break;
5974f3865fbSRichard Purdie                     PULLBYTE();
5984f3865fbSRichard Purdie                 }
5994f3865fbSRichard Purdie                 DROPBITS(last.bits);
6004f3865fbSRichard Purdie             }
6014f3865fbSRichard Purdie             DROPBITS(this.bits);
6024f3865fbSRichard Purdie             state->length = (unsigned)this.val;
6034f3865fbSRichard Purdie             if ((int)(this.op) == 0) {
6044f3865fbSRichard Purdie                 state->mode = LIT;
6054f3865fbSRichard Purdie                 break;
6064f3865fbSRichard Purdie             }
6074f3865fbSRichard Purdie             if (this.op & 32) {
6084f3865fbSRichard Purdie                 state->mode = TYPE;
6094f3865fbSRichard Purdie                 break;
6104f3865fbSRichard Purdie             }
6114f3865fbSRichard Purdie             if (this.op & 64) {
6124f3865fbSRichard Purdie                 strm->msg = (char *)"invalid literal/length code";
6134f3865fbSRichard Purdie                 state->mode = BAD;
6144f3865fbSRichard Purdie                 break;
6154f3865fbSRichard Purdie             }
6164f3865fbSRichard Purdie             state->extra = (unsigned)(this.op) & 15;
6174f3865fbSRichard Purdie             state->mode = LENEXT;
61836f9ff9eSGustavo A. R. Silva 	    fallthrough;
6194f3865fbSRichard Purdie         case LENEXT:
6204f3865fbSRichard Purdie             if (state->extra) {
6214f3865fbSRichard Purdie                 NEEDBITS(state->extra);
6224f3865fbSRichard Purdie                 state->length += BITS(state->extra);
6234f3865fbSRichard Purdie                 DROPBITS(state->extra);
6244f3865fbSRichard Purdie             }
6254f3865fbSRichard Purdie             state->mode = DIST;
62636f9ff9eSGustavo A. R. Silva 	    fallthrough;
6274f3865fbSRichard Purdie         case DIST:
6284f3865fbSRichard Purdie             for (;;) {
6294f3865fbSRichard Purdie                 this = state->distcode[BITS(state->distbits)];
6304f3865fbSRichard Purdie                 if ((unsigned)(this.bits) <= bits) break;
6314f3865fbSRichard Purdie                 PULLBYTE();
6324f3865fbSRichard Purdie             }
6334f3865fbSRichard Purdie             if ((this.op & 0xf0) == 0) {
6344f3865fbSRichard Purdie                 last = this;
6354f3865fbSRichard Purdie                 for (;;) {
6364f3865fbSRichard Purdie                     this = state->distcode[last.val +
6374f3865fbSRichard Purdie                             (BITS(last.bits + last.op) >> last.bits)];
6384f3865fbSRichard Purdie                     if ((unsigned)(last.bits + this.bits) <= bits) break;
6394f3865fbSRichard Purdie                     PULLBYTE();
6404f3865fbSRichard Purdie                 }
6414f3865fbSRichard Purdie                 DROPBITS(last.bits);
6424f3865fbSRichard Purdie             }
6434f3865fbSRichard Purdie             DROPBITS(this.bits);
6444f3865fbSRichard Purdie             if (this.op & 64) {
6454f3865fbSRichard Purdie                 strm->msg = (char *)"invalid distance code";
6464f3865fbSRichard Purdie                 state->mode = BAD;
6474f3865fbSRichard Purdie                 break;
6484f3865fbSRichard Purdie             }
6494f3865fbSRichard Purdie             state->offset = (unsigned)this.val;
6504f3865fbSRichard Purdie             state->extra = (unsigned)(this.op) & 15;
6514f3865fbSRichard Purdie             state->mode = DISTEXT;
65236f9ff9eSGustavo A. R. Silva 	    fallthrough;
6534f3865fbSRichard Purdie         case DISTEXT:
6544f3865fbSRichard Purdie             if (state->extra) {
6554f3865fbSRichard Purdie                 NEEDBITS(state->extra);
6564f3865fbSRichard Purdie                 state->offset += BITS(state->extra);
6574f3865fbSRichard Purdie                 DROPBITS(state->extra);
6584f3865fbSRichard Purdie             }
6594f3865fbSRichard Purdie #ifdef INFLATE_STRICT
6604f3865fbSRichard Purdie             if (state->offset > state->dmax) {
6614f3865fbSRichard Purdie                 strm->msg = (char *)"invalid distance too far back";
6624f3865fbSRichard Purdie                 state->mode = BAD;
6634f3865fbSRichard Purdie                 break;
6644f3865fbSRichard Purdie             }
6654f3865fbSRichard Purdie #endif
6664f3865fbSRichard Purdie             if (state->offset > state->whave + out - left) {
6674f3865fbSRichard Purdie                 strm->msg = (char *)"invalid distance too far back";
6684f3865fbSRichard Purdie                 state->mode = BAD;
6694f3865fbSRichard Purdie                 break;
6704f3865fbSRichard Purdie             }
6714f3865fbSRichard Purdie             state->mode = MATCH;
67236f9ff9eSGustavo A. R. Silva 	    fallthrough;
6734f3865fbSRichard Purdie         case MATCH:
6744f3865fbSRichard Purdie             if (left == 0) goto inf_leave;
6754f3865fbSRichard Purdie             copy = out - left;
6764f3865fbSRichard Purdie             if (state->offset > copy) {         /* copy from window */
6774f3865fbSRichard Purdie                 copy = state->offset - copy;
6784f3865fbSRichard Purdie                 if (copy > state->write) {
6794f3865fbSRichard Purdie                     copy -= state->write;
6804f3865fbSRichard Purdie                     from = state->window + (state->wsize - copy);
6814f3865fbSRichard Purdie                 }
6824f3865fbSRichard Purdie                 else
6834f3865fbSRichard Purdie                     from = state->window + (state->write - copy);
6844f3865fbSRichard Purdie                 if (copy > state->length) copy = state->length;
6854f3865fbSRichard Purdie             }
6864f3865fbSRichard Purdie             else {                              /* copy from output */
6874f3865fbSRichard Purdie                 from = put - state->offset;
6884f3865fbSRichard Purdie                 copy = state->length;
6894f3865fbSRichard Purdie             }
6904f3865fbSRichard Purdie             if (copy > left) copy = left;
6914f3865fbSRichard Purdie             left -= copy;
6924f3865fbSRichard Purdie             state->length -= copy;
6934f3865fbSRichard Purdie             do {
6944f3865fbSRichard Purdie                 *put++ = *from++;
6954f3865fbSRichard Purdie             } while (--copy);
6964f3865fbSRichard Purdie             if (state->length == 0) state->mode = LEN;
6974f3865fbSRichard Purdie             break;
6984f3865fbSRichard Purdie         case LIT:
6994f3865fbSRichard Purdie             if (left == 0) goto inf_leave;
7004f3865fbSRichard Purdie             *put++ = (unsigned char)(state->length);
7014f3865fbSRichard Purdie             left--;
7024f3865fbSRichard Purdie             state->mode = LEN;
7034f3865fbSRichard Purdie             break;
7044f3865fbSRichard Purdie         case CHECK:
7054f3865fbSRichard Purdie             if (state->wrap) {
7064f3865fbSRichard Purdie                 NEEDBITS(32);
7074f3865fbSRichard Purdie                 out -= left;
7084f3865fbSRichard Purdie                 strm->total_out += out;
7094f3865fbSRichard Purdie                 state->total += out;
71012619610SMikhail Zaslonko                 if (INFLATE_NEED_CHECKSUM(strm) && out)
7114f3865fbSRichard Purdie                     strm->adler = state->check =
7124f3865fbSRichard Purdie                         UPDATE(state->check, put - out, out);
7134f3865fbSRichard Purdie                 out = left;
7144f3865fbSRichard Purdie                 if ((
7154f3865fbSRichard Purdie                      REVERSE(hold)) != state->check) {
7164f3865fbSRichard Purdie                     strm->msg = (char *)"incorrect data check";
7174f3865fbSRichard Purdie                     state->mode = BAD;
7184f3865fbSRichard Purdie                     break;
7194f3865fbSRichard Purdie                 }
7204f3865fbSRichard Purdie                 INITBITS();
7214f3865fbSRichard Purdie             }
7224f3865fbSRichard Purdie             state->mode = DONE;
72336f9ff9eSGustavo A. R. Silva 	    fallthrough;
7244f3865fbSRichard Purdie         case DONE:
7254f3865fbSRichard Purdie             ret = Z_STREAM_END;
7264f3865fbSRichard Purdie             goto inf_leave;
7274f3865fbSRichard Purdie         case BAD:
7284f3865fbSRichard Purdie             ret = Z_DATA_ERROR;
7294f3865fbSRichard Purdie             goto inf_leave;
7304f3865fbSRichard Purdie         case MEM:
7314f3865fbSRichard Purdie             return Z_MEM_ERROR;
7324f3865fbSRichard Purdie         case SYNC:
7331da177e4SLinus Torvalds         default:
7341da177e4SLinus Torvalds             return Z_STREAM_ERROR;
7351da177e4SLinus Torvalds         }
7364f3865fbSRichard Purdie 
7374f3865fbSRichard Purdie     /*
7384f3865fbSRichard Purdie        Return from inflate(), updating the total counts and the check value.
7394f3865fbSRichard Purdie        If there was no progress during the inflate() call, return a buffer
7404f3865fbSRichard Purdie        error.  Call zlib_updatewindow() to create and/or update the window state.
7414f3865fbSRichard Purdie      */
7424f3865fbSRichard Purdie   inf_leave:
7434f3865fbSRichard Purdie     RESTORE();
74412619610SMikhail Zaslonko     if (INFLATE_NEED_UPDATEWINDOW(strm) &&
74512619610SMikhail Zaslonko             (state->wsize || (state->mode < CHECK && out != strm->avail_out)))
7464f3865fbSRichard Purdie         zlib_updatewindow(strm, out);
7474f3865fbSRichard Purdie 
7484f3865fbSRichard Purdie     in -= strm->avail_in;
7494f3865fbSRichard Purdie     out -= strm->avail_out;
7504f3865fbSRichard Purdie     strm->total_in += in;
7514f3865fbSRichard Purdie     strm->total_out += out;
7524f3865fbSRichard Purdie     state->total += out;
75312619610SMikhail Zaslonko     if (INFLATE_NEED_CHECKSUM(strm) && state->wrap && out)
7544f3865fbSRichard Purdie         strm->adler = state->check =
7554f3865fbSRichard Purdie             UPDATE(state->check, strm->next_out - out, out);
7564f3865fbSRichard Purdie 
7574f3865fbSRichard Purdie     strm->data_type = state->bits + (state->last ? 64 : 0) +
7584f3865fbSRichard Purdie                       (state->mode == TYPE ? 128 : 0);
759f0ac6758SRichard Purdie 
760f0ac6758SRichard Purdie     if (flush == Z_PACKET_FLUSH && ret == Z_OK &&
761f0ac6758SRichard Purdie             strm->avail_out != 0 && strm->avail_in == 0)
762f0ac6758SRichard Purdie 		return zlib_inflateSyncPacket(strm);
763f0ac6758SRichard Purdie 
7644f3865fbSRichard Purdie     if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
7654f3865fbSRichard Purdie         ret = Z_BUF_ERROR;
7664f3865fbSRichard Purdie 
7674f3865fbSRichard Purdie     return ret;
7684f3865fbSRichard Purdie }
7694f3865fbSRichard Purdie 
zlib_inflateEnd(z_streamp strm)7704f3865fbSRichard Purdie int zlib_inflateEnd(z_streamp strm)
7714f3865fbSRichard Purdie {
7724f3865fbSRichard Purdie     if (strm == NULL || strm->state == NULL)
7734f3865fbSRichard Purdie         return Z_STREAM_ERROR;
7744f3865fbSRichard Purdie     return Z_OK;
7754f3865fbSRichard Purdie }
7764f3865fbSRichard Purdie 
7774f3865fbSRichard Purdie /*
7784f3865fbSRichard Purdie  * This subroutine adds the data at next_in/avail_in to the output history
7794f3865fbSRichard Purdie  * without performing any output.  The output buffer must be "caught up";
7804f3865fbSRichard Purdie  * i.e. no pending output but this should always be the case. The state must
7814f3865fbSRichard Purdie  * be waiting on the start of a block (i.e. mode == TYPE or HEAD).  On exit,
7824f3865fbSRichard Purdie  * the output will also be caught up, and the checksum will have been updated
7834f3865fbSRichard Purdie  * if need be.
7844f3865fbSRichard Purdie  */
zlib_inflateIncomp(z_stream * z)7854f3865fbSRichard Purdie int zlib_inflateIncomp(z_stream *z)
7864f3865fbSRichard Purdie {
7874f3865fbSRichard Purdie     struct inflate_state *state = (struct inflate_state *)z->state;
7884f3865fbSRichard Purdie     Byte *saved_no = z->next_out;
7894f3865fbSRichard Purdie     uInt saved_ao = z->avail_out;
7904f3865fbSRichard Purdie 
7914f3865fbSRichard Purdie     if (state->mode != TYPE && state->mode != HEAD)
7924f3865fbSRichard Purdie 	return Z_DATA_ERROR;
7934f3865fbSRichard Purdie 
7944f3865fbSRichard Purdie     /* Setup some variables to allow misuse of updateWindow */
7954f3865fbSRichard Purdie     z->avail_out = 0;
7968336793bSDenys Vlasenko     z->next_out = (unsigned char*)z->next_in + z->avail_in;
7974f3865fbSRichard Purdie 
7984f3865fbSRichard Purdie     zlib_updatewindow(z, z->avail_in);
7994f3865fbSRichard Purdie 
8004f3865fbSRichard Purdie     /* Restore saved variables */
8014f3865fbSRichard Purdie     z->avail_out = saved_ao;
8024f3865fbSRichard Purdie     z->next_out = saved_no;
8034f3865fbSRichard Purdie 
8044f3865fbSRichard Purdie     z->adler = state->check =
8054f3865fbSRichard Purdie         UPDATE(state->check, z->next_in, z->avail_in);
8064f3865fbSRichard Purdie 
8074f3865fbSRichard Purdie     z->total_out += z->avail_in;
8084f3865fbSRichard Purdie     z->total_in += z->avail_in;
8094f3865fbSRichard Purdie     z->next_in += z->avail_in;
8104f3865fbSRichard Purdie     state->total += z->avail_in;
8114f3865fbSRichard Purdie     z->avail_in = 0;
8124f3865fbSRichard Purdie 
8134f3865fbSRichard Purdie     return Z_OK;
8144f3865fbSRichard Purdie }
815