17eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* inflate.c -- zlib decompression 27eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * Copyright (C) 1995-2012 Mark Adler 37eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * For conditions of distribution and use, see copyright notice in zlib.h 47eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 57eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 67eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* 77eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * Change history: 87eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 97eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta0 24 Nov 2002 107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - First version -- complete rewrite of inflate to simplify code, avoid 117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * creation of window when not needed, minimize use of window when it is 127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * needed, make inffast.c even faster, implement gzip decoding, and to 137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * improve code readability and style over the previous zlib inflate code 147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta1 25 Nov 2002 167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Use pointers for available input and output checking in inffast.c 177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Remove input and output counters in inffast.c 187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Remove unnecessary second byte pull from length extra in inffast.c 207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Unroll direct copy to three copies per loop in inffast.c 217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta2 4 Dec 2002 237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Change external routine names to reduce potential conflicts 247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Correct filename to inffixed.h for fixed tables in inflate.c 257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Make hbuf[] unsigned char to match parameter type in inflate.c 267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) 277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * to avoid negation problem on Alphas (64 bit) in inflate.c 287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta3 22 Dec 2002 307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Add comments on state->bits assertion in inffast.c 317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Add comments on op field in inftrees.h 327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Fix bug in reuse of allocated window after inflateReset() 337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Remove bit fields--back to byte structure for speed 347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths 357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Change post-increments to pre-increments in inflate_fast(), PPC biased? 367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Add compile time option, POSTINC, to use post-increments instead (Intel?) 377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Make MATCH copy in inflate() much faster for when inflate_fast() not used 387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Use local copies of stream next and avail values, as well as local bit 397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * buffer and bit count in inflate()--for speed when inflate_fast() not used 407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta4 1 Jan 2003 427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings 437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Move a comment on output buffer sizes from inffast.c to inflate.c 447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Add comments in inffast.c to introduce the inflate_fast() routine 457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Rearrange window copies in inflate_fast() for speed and simplification 467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Unroll last copy for window match in inflate_fast() 477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Use local copies of window variables in inflate_fast() for speed 487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Pull out common wnext == 0 case for speed in inflate_fast() 497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Make op and len in inflate_fast() unsigned for consistency 507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Add FAR to lcode and dcode declarations in inflate_fast() 517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Simplified bad distance check in inflate_fast() 527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new 537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * source file infback.c to provide a call-back interface to inflate for 547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * programs like gzip and unzip -- uses window as output buffer to avoid 557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * window copying 567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta5 1 Jan 2003 587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Improved inflateBack() interface to allow the caller to provide initial 597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * input in strm. 607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Fixed stored blocks bug in inflateBack() 617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta6 4 Jan 2003 637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Added comments in inffast.c on effectiveness of POSTINC 647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Typecasting all around to reduce compiler warnings 657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Changed loops from while (1) or do {} while (1) to for (;;), again to 667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * make compilers happy 677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Changed type of window in inflateBackInit() to unsigned char * 687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.beta7 27 Jan 2003 707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Changed many types to unsigned or unsigned short to avoid warnings 717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Added inflateCopy() function 727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 1.2.0 9 Mar 2003 747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Changed inflateBack() interface to provide separate opaque descriptors 757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * for the in() and out() functions 767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Changed inflateBack() argument and in_func typedef to swap the length 777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * and buffer address return values for the input function 787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * - Check next_in and next_out for Z_NULL on entry to inflate() 797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * 807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. 817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "zutil.h" 847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "inftrees.h" 857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "inflate.h" 867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include "inffast.h" 877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef MAKEFIXED 897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel# ifndef BUILDFIXED 907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel# define BUILDFIXED 917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel# endif 927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* function prototypes */ 957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal void fixedtables OF((struct inflate_state FAR *state)); 967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal int updatewindow OF((z_streamp strm, const unsigned char FAR *end, 977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned copy)); 987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef BUILDFIXED 997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel void makefixed OF((void)); 1007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 1017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, 1027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned len)); 1037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateResetKeep(strm) 1057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 1067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 1077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 1087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 1107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 1117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->total_in = strm->total_out = state->total = 0; 1127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = Z_NULL; 1137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->wrap) /* to support ill-conceived Java test suite */ 1147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->adler = state->wrap & 1; 1157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = HEAD; 1167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->last = 0; 1177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->havedict = 0; 1187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->dmax = 32768U; 1197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head = Z_NULL; 1207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->hold = 0; 1217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->bits = 0; 1227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->lencode = state->distcode = state->next = state->codes; 1237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->sane = 1; 1247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->back = -1; 1257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: reset\n")); 1267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_OK; 1277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 1287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateReset(strm) 1307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 1317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 1327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 1337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 1357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 1367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->wsize = 0; 1377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->whave = 0; 1387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->wnext = 0; 1397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return inflateResetKeep(strm); 1407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 1417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateReset2(strm, windowBits) 1437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 1447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint windowBits; 1457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 1467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int wrap; 1477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 1487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* get the state */ 1507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 1517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 1527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* extract wrap request from windowBits parameter */ 1547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (windowBits < 0) { 1557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel wrap = 0; 1567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel windowBits = -windowBits; 1577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 1587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 1597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel wrap = (windowBits >> 4) + 1; 1607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP 1617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (windowBits < 48) 1627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel windowBits &= 15; 1637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 1647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 1657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* set number of window bits, free window if different */ 1677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (windowBits && (windowBits < 8 || windowBits > 15)) 1687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_STREAM_ERROR; 1697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { 1707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ZFREE(strm, state->window); 1717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->window = Z_NULL; 1727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 1737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* update state and reset the rest of it */ 1757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->wrap = wrap; 1767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->wbits = (unsigned)windowBits; 1777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return inflateReset(strm); 1787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 1797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) 1817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 1827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint windowBits; 1837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconst char *version; 1847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint stream_size; 1857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 1867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int ret; 1877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 1887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 1897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 1907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel stream_size != (int)(sizeof(z_stream))) 1917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_VERSION_ERROR; 1927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL) return Z_STREAM_ERROR; 1937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = Z_NULL; /* in case we return an error */ 1947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm->zalloc == (alloc_func)0) { 1957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Z_SOLO 1967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_STREAM_ERROR; 1977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else 1987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->zalloc = zcalloc; 1997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->opaque = (voidpf)0; 2007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 2017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm->zfree == (free_func)0) 2037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef Z_SOLO 2047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_STREAM_ERROR; 2057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else 2067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->zfree = zcfree; 2077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 2087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *) 2097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ZALLOC(strm, 1, sizeof(struct inflate_state)); 2107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state == Z_NULL) return Z_MEM_ERROR; 2117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: allocated\n")); 2127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->state = (struct internal_state FAR *)state; 2137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->window = Z_NULL; 2147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ret = inflateReset2(strm, windowBits); 2157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (ret != Z_OK) { 2167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ZFREE(strm, state); 2177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->state = Z_NULL; 2187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return ret; 2207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 2217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateInit_(strm, version, stream_size) 2237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 2247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconst char *version; 2257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint stream_size; 2267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 2277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return inflateInit2_(strm, DEF_WBITS, version, stream_size); 2287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 2297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflatePrime(strm, bits, value) 2317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 2327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint bits; 2337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint value; 2347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 2357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 2367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 2387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 2397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (bits < 0) { 2407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->hold = 0; 2417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->bits = 0; 2427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_OK; 2437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; 2457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel value &= (1L << bits) - 1; 2467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->hold += value << state->bits; 2477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->bits += bits; 2487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_OK; 2497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 2507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* 2527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Return state with length and distance decoding tables and index sizes set to 2537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel fixed code decoding. Normally this returns fixed tables from inffixed.h. 2547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel If BUILDFIXED is defined, then instead this routine builds the tables the 2557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel first time it's called, and returns those tables the first time and 2567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel thereafter. This reduces the size of the code by about 2K bytes, in 2577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel exchange for a little execution time. However, BUILDFIXED should not be 2587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel used for threaded applications, since the rewriting of the tables and virgin 2597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel may not be thread-safe. 2607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 2617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal void fixedtables(state) 2627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielstruct inflate_state FAR *state; 2637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 2647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef BUILDFIXED 2657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static int virgin = 1; 2667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static code *lenfix, *distfix; 2677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static code fixed[544]; 2687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* build fixed huffman tables if first call (may not be thread safe) */ 2707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (virgin) { 2717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned sym, bits; 2727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static code *next; 2737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* literal/length table */ 2757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel sym = 0; 2767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (sym < 144) state->lens[sym++] = 8; 2777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (sym < 256) state->lens[sym++] = 9; 2787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (sym < 280) state->lens[sym++] = 7; 2797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (sym < 288) state->lens[sym++] = 8; 2807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next = fixed; 2817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel lenfix = next; 2827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel bits = 9; 2837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); 2847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* distance table */ 2867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel sym = 0; 2877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (sym < 32) state->lens[sym++] = 5; 2887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel distfix = next; 2897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel bits = 5; 2907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); 2917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 2927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* do this just once */ 2937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel virgin = 0; 2947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 2957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else /* !BUILDFIXED */ 2967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel# include "inffixed.h" 2977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif /* BUILDFIXED */ 2987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->lencode = lenfix; 2997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->lenbits = 9; 3007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->distcode = distfix; 3017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->distbits = 5; 3027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 3037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef MAKEFIXED 3057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#include <stdio.h> 3067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* 3087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also 3097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel defines BUILDFIXED, so the tables are built on the fly. makefixed() writes 3107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel those tables to stdout, which would be piped to inffixed.h. A small program 3117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel can simply call makefixed to do this: 3127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel void makefixed(void); 3147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int main(void) 3167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel { 3177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel makefixed(); 3187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 3197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Then that can be linked with zlib built with MAKEFIXED defined and run: 3227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel a.out > inffixed.h 3247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 3257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielvoid makefixed() 3267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 3277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned low, size; 3287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state state; 3297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel fixedtables(&state); 3317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel puts(" /* inffixed.h -- table for decoding fixed codes"); 3327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel puts(" * Generated automatically by makefixed()."); 3337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel puts(" */"); 3347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel puts(""); 3357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel puts(" /* WARNING: this file should *not* be used by applications."); 3367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel puts(" It is part of the implementation of this library and is"); 3377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel puts(" subject to change. Applications should only use zlib.h."); 3387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel puts(" */"); 3397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel puts(""); 3407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel size = 1U << 9; 3417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel printf(" static const code lenfix[%u] = {", size); 3427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel low = 0; 3437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (;;) { 3447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((low % 7) == 0) printf("\n "); 3457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, 3467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state.lencode[low].bits, state.lencode[low].val); 3477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (++low == size) break; 3487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel putchar(','); 3497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel puts("\n };"); 3517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel size = 1U << 5; 3527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel printf("\n static const code distfix[%u] = {", size); 3537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel low = 0; 3547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (;;) { 3557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((low % 6) == 0) printf("\n "); 3567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, 3577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state.distcode[low].val); 3587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (++low == size) break; 3597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel putchar(','); 3607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel puts("\n };"); 3627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 3637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif /* MAKEFIXED */ 3647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* 3667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Update the window with the last wsize (normally 32K) bytes written before 3677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel returning. If window does not exist yet, create it. This is only called 3687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel when a window is already in use, or when output has been written during this 3697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel inflate call, but the end of the deflate stream has not been reached yet. 3707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel It is also called to create a window for dictionary data when a dictionary 3717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel is loaded. 3727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Providing output buffers larger than 32K to inflate() should provide a speed 3747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel advantage, since only the last 32K of output is copied to the sliding window 3757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel upon return from inflate(), and since all distances after the first 32K of 3767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output will fall in the output data, making match copies simpler and faster. 3777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel The advantage may be dependent on the size of the processor's data caches. 3787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 3797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal int updatewindow(strm, end, copy) 3807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 3817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconst Bytef *end; 3827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielunsigned copy; 3837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 3847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 3857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned dist; 3867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 3887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if it hasn't been done already, allocate space for the window */ 3907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->window == Z_NULL) { 3917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->window = (unsigned char FAR *) 3927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ZALLOC(strm, 1U << state->wbits, 3937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel sizeof(unsigned char)); 3947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->window == Z_NULL) return 1; 3957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 3967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 3977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if window not in use yet, initialize */ 3987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->wsize == 0) { 3997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->wsize = 1U << state->wbits; 4007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->wnext = 0; 4017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->whave = 0; 4027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* copy state->wsize or less output bytes into the circular window */ 4057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy >= state->wsize) { 4067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel zmemcpy(state->window, end - state->wsize, state->wsize); 4077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->wnext = 0; 4087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->whave = state->wsize; 4097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 4117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel dist = state->wsize - state->wnext; 4127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (dist > copy) dist = copy; 4137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel zmemcpy(state->window + state->wnext, end - copy, dist); 4147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy -= dist; 4157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy) { 4167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel zmemcpy(state->window, end - copy, copy); 4177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->wnext = copy; 4187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->whave = state->wsize; 4197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 4217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->wnext += dist; 4227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->wnext == state->wsize) state->wnext = 0; 4237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->whave < state->wsize) state->whave += dist; 4247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 4267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return 0; 4277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 4287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Macros for inflate(): */ 4307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* check function to use adler32() for zlib or crc32() for gzip */ 4327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP 4337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel# define UPDATE(check, buf, len) \ 4347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) 4357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else 4367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel# define UPDATE(check, buf, len) adler32(check, buf, len) 4377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 4387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* check macros for header crc */ 4407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP 4417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel# define CRC2(check, word) \ 4427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel do { \ 4437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel hbuf[0] = (unsigned char)(word); \ 4447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel hbuf[1] = (unsigned char)((word) >> 8); \ 4457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel check = crc32(check, hbuf, 2); \ 4467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } while (0) 4477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel# define CRC4(check, word) \ 4497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel do { \ 4507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel hbuf[0] = (unsigned char)(word); \ 4517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel hbuf[1] = (unsigned char)((word) >> 8); \ 4527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel hbuf[2] = (unsigned char)((word) >> 16); \ 4537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel hbuf[3] = (unsigned char)((word) >> 24); \ 4547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel check = crc32(check, hbuf, 4); \ 4557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } while (0) 4567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 4577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Load registers with state in inflate() for speed */ 4597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define LOAD() \ 4607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel do { \ 4617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel put = strm->next_out; \ 4627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel left = strm->avail_out; \ 4637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next = strm->next_in; \ 4647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel have = strm->avail_in; \ 4657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel hold = state->hold; \ 4667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel bits = state->bits; \ 4677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } while (0) 4687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Restore state from registers in inflate() */ 4707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define RESTORE() \ 4717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel do { \ 4727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->next_out = put; \ 4737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->avail_out = left; \ 4747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->next_in = next; \ 4757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->avail_in = have; \ 4767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->hold = hold; \ 4777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->bits = bits; \ 4787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } while (0) 4797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Clear the input bit accumulator */ 4817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define INITBITS() \ 4827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel do { \ 4837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel hold = 0; \ 4847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel bits = 0; \ 4857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } while (0) 4867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Get a byte of input into the bit accumulator, or return from inflate() 4887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if there is no input available. */ 4897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define PULLBYTE() \ 4907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel do { \ 4917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (have == 0) goto inf_leave; \ 4927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel have--; \ 4937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel hold += (unsigned long)(*next++) << bits; \ 4947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel bits += 8; \ 4957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } while (0) 4967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 4977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Assure that there are at least n bits in the bit accumulator. If there is 4987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel not enough available input to do that, then return from inflate(). */ 4997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define NEEDBITS(n) \ 5007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel do { \ 5017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (bits < (unsigned)(n)) \ 5027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PULLBYTE(); \ 5037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } while (0) 5047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Return the low n bits of the bit accumulator (n < 16) */ 5067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define BITS(n) \ 5077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ((unsigned)hold & ((1U << (n)) - 1)) 5087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Remove n bits from the bit accumulator */ 5107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define DROPBITS(n) \ 5117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel do { \ 5127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel hold >>= (n); \ 5137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel bits -= (unsigned)(n); \ 5147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } while (0) 5157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* Remove zero to seven bits as needed to go to a byte boundary */ 5177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#define BYTEBITS() \ 5187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel do { \ 5197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel hold >>= bits & 7; \ 5207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel bits -= bits & 7; \ 5217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } while (0) 5227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* 5247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel inflate() uses a state machine to process as much input data and generate as 5257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel much output data as possible before returning. The state machine is 5267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel structured roughly as follows: 5277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (;;) switch (state) { 5297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ... 5307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case STATEn: 5317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (not enough input data or output space to make progress) 5327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return; 5337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ... make progress ... 5347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = STATEm; 5357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 5367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ... 5377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel so when inflate() is called again, the same case is attempted again, and 5407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if the appropriate resources are provided, the machine proceeds to the 5417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next state. The NEEDBITS() macro is usually the way the state evaluates 5427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel whether it can proceed or should return. NEEDBITS() does the return if 5437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the requested bits are not available. The typical use of the BITS macros 5447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel is: 5457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(n); 5477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ... do something with BITS(n) ... 5487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(n); 5497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel where NEEDBITS(n) either returns from inflate() if there isn't enough 5517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel input left to load n bits into the accumulator, or it continues. BITS(n) 5527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel gives the low n bits in the accumulator. When done, DROPBITS(n) drops 5537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the low n bits off the accumulator. INITBITS() clears the accumulator 5547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel and sets the number of available bits to zero. BYTEBITS() discards just 5557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel enough bits to put the accumulator on a byte boundary. After BYTEBITS() 5567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. 5577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return 5597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if there is no input available. The decoding of variable length codes uses 5607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PULLBYTE() directly in order to pull just enough bytes to decode the next 5617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel code, and no more. 5627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Some states loop until they get enough input, making sure that enough 5647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state information is maintained to continue the loop where it left off 5657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if NEEDBITS() returns in the loop. For example, want, need, and keep 5667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel would all have to actually be part of the saved state in case NEEDBITS() 5677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel returns: 5687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case STATEw: 5707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (want < need) { 5717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(n); 5727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel keep[want++] = BITS(n); 5737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(n); 5747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 5757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = STATEx; 5767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case STATEx: 5777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel As shown above, if the next state is also the next case, then the break 5797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel is omitted. 5807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel A state may also return if there is not enough output space available to 5827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel complete that state. Those states are copying stored data, writing a 5837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel literal byte, and copying a matching string. 5847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel When returning, a "goto inf_leave" is used to update the total counters, 5867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel update the check value, and determine whether any progress has been made 5877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel during that inflate() call in order to return the proper return code. 5887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Progress is defined as a change in either strm->avail_in or strm->avail_out. 5897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel When there is a window, goto inf_leave will update the window with the last 5907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output written. If a goto inf_leave occurs in the middle of decompression 5917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel and there is no window currently, goto inf_leave will create one and copy 5927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel output to the window for the next call of inflate(). 5937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 5947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel In this implementation, the flush parameter of inflate() only affects the 5957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return code (per zlib.h). inflate() always writes as much as possible to 5967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->next_out, given the space available and the provided input--the effect 5977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers 5987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel the allocation of and copying into a sliding window until necessary, which 5997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel provides the effect documented in zlib.h for Z_FINISH when the entire input 6007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel stream available. So the only thing the flush parameter actually does is: 6017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it 6027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel will return Z_BUF_ERROR if it has not reached the end of the stream. 6037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 6047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflate(strm, flush) 6067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 6077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint flush; 6087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 6097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 6107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel z_const unsigned char FAR *next; /* next input */ 6117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned char FAR *put; /* next output */ 6127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned have, left; /* available input and output */ 6137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned long hold; /* bit buffer */ 6147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned bits; /* bits in bit buffer */ 6157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned in, out; /* save starting available input and output */ 6167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned copy; /* number of stored or match bytes to copy */ 6177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned char FAR *from; /* where to copy match bytes from */ 6187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel code here; /* current decoding table entry */ 6197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel code last; /* parent table entry */ 6207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned len; /* length to copy for repeats, bits to drop */ 6217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int ret; /* return code */ 6227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP 6237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ 6247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 6257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel static const unsigned short order[19] = /* permutation of code lengths */ 6267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 6277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || 6297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (strm->next_in == Z_NULL && strm->avail_in != 0)) 6307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_STREAM_ERROR; 6317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 6327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 6337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ 6347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel LOAD(); 6357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel in = have; 6367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel out = left; 6377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ret = Z_OK; 6387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (;;) 6397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel switch (state->mode) { 6407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case HEAD: 6417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->wrap == 0) { 6427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = TYPEDO; 6437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 6447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(16); 6467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP 6477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ 6487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->check = crc32(0L, Z_NULL, 0); 6497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel CRC2(state->check, hold); 6507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel INITBITS(); 6517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = FLAGS; 6527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 6537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->flags = 0; /* expect zlib header */ 6557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->head != Z_NULL) 6567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->done = -1; 6577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (!(state->wrap & 1) || /* check if zlib header allowed */ 6587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else 6597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ( 6607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 6617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ((BITS(8) << 8) + (hold >> 8)) % 31) { 6627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"incorrect header check"; 6637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 6647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 6657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (BITS(4) != Z_DEFLATED) { 6677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"unknown compression method"; 6687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 6697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 6707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(4); 6727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel len = BITS(4) + 8; 6737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->wbits == 0) 6747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->wbits = len; 6757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (len > state->wbits) { 6767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"invalid window size"; 6777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 6787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 6797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->dmax = 1U << len; 6817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: zlib header ok\n")); 6827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->adler = state->check = adler32(0L, Z_NULL, 0); 6837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = hold & 0x200 ? DICTID : TYPE; 6847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel INITBITS(); 6857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 6867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP 6877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case FLAGS: 6887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(16); 6897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->flags = (int)(hold); 6907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((state->flags & 0xff) != Z_DEFLATED) { 6917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"unknown compression method"; 6927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 6937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 6947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 6957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->flags & 0xe000) { 6967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"unknown header flags set"; 6977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 6987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 6997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->head != Z_NULL) 7017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->text = (int)((hold >> 8) & 1); 7027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->flags & 0x0200) CRC2(state->check, hold); 7037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel INITBITS(); 7047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = TIME; 7057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case TIME: 7067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(32); 7077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->head != Z_NULL) 7087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->time = hold; 7097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->flags & 0x0200) CRC4(state->check, hold); 7107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel INITBITS(); 7117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = OS; 7127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case OS: 7137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(16); 7147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->head != Z_NULL) { 7157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->xflags = (int)(hold & 0xff); 7167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->os = (int)(hold >> 8); 7177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->flags & 0x0200) CRC2(state->check, hold); 7197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel INITBITS(); 7207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = EXLEN; 7217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case EXLEN: 7227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->flags & 0x0400) { 7237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(16); 7247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->length = (unsigned)(hold); 7257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->head != Z_NULL) 7267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->extra_len = (unsigned)hold; 7277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->flags & 0x0200) CRC2(state->check, hold); 7287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel INITBITS(); 7297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (state->head != Z_NULL) 7317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->extra = Z_NULL; 7327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = EXTRA; 7337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case EXTRA: 7347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->flags & 0x0400) { 7357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy = state->length; 7367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy > have) copy = have; 7377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy) { 7387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->head != Z_NULL && 7397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->extra != Z_NULL) { 7407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel len = state->head->extra_len - state->length; 7417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel zmemcpy(state->head->extra + len, next, 7427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel len + copy > state->head->extra_max ? 7437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->extra_max - len : copy); 7447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->flags & 0x0200) 7467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->check = crc32(state->check, next, copy); 7477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel have -= copy; 7487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next += copy; 7497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->length -= copy; 7507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->length) goto inf_leave; 7527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->length = 0; 7547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = NAME; 7557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case NAME: 7567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->flags & 0x0800) { 7577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (have == 0) goto inf_leave; 7587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy = 0; 7597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel do { 7607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel len = (unsigned)(next[copy++]); 7617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->head != Z_NULL && 7627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->name != Z_NULL && 7637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->length < state->head->name_max) 7647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->name[state->length++] = len; 7657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } while (len && copy < have); 7667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->flags & 0x0200) 7677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->check = crc32(state->check, next, copy); 7687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel have -= copy; 7697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next += copy; 7707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (len) goto inf_leave; 7717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (state->head != Z_NULL) 7737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->name = Z_NULL; 7747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->length = 0; 7757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = COMMENT; 7767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case COMMENT: 7777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->flags & 0x1000) { 7787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (have == 0) goto inf_leave; 7797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy = 0; 7807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel do { 7817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel len = (unsigned)(next[copy++]); 7827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->head != Z_NULL && 7837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->comment != Z_NULL && 7847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->length < state->head->comm_max) 7857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->comment[state->length++] = len; 7867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } while (len && copy < have); 7877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->flags & 0x0200) 7887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->check = crc32(state->check, next, copy); 7897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel have -= copy; 7907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next += copy; 7917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (len) goto inf_leave; 7927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 7937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (state->head != Z_NULL) 7947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->comment = Z_NULL; 7957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = HCRC; 7967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case HCRC: 7977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->flags & 0x0200) { 7987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(16); 7997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (hold != (state->check & 0xffff)) { 8007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"header crc mismatch"; 8017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 8027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 8037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 8047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel INITBITS(); 8057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 8067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->head != Z_NULL) { 8077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->hcrc = (int)((state->flags >> 9) & 1); 8087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head->done = 1; 8097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 8107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->adler = state->check = crc32(0L, Z_NULL, 0); 8117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = TYPE; 8127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 8137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 8147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case DICTID: 8157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(32); 8167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->adler = state->check = ZSWAP32(hold); 8177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel INITBITS(); 8187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = DICT; 8197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case DICT: 8207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->havedict == 0) { 8217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel RESTORE(); 8227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_NEED_DICT; 8237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 8247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->adler = state->check = adler32(0L, Z_NULL, 0); 8257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = TYPE; 8267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case TYPE: 8277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; 8287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case TYPEDO: 8297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->last) { 8307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel BYTEBITS(); 8317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = CHECK; 8327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 8337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 8347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(3); 8357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->last = BITS(1); 8367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(1); 8377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel switch (BITS(2)) { 8387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 0: /* stored block */ 8397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: stored block%s\n", 8407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->last ? " (last)" : "")); 8417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = STORED; 8427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 8437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 1: /* fixed block */ 8447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel fixedtables(state); 8457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: fixed codes block%s\n", 8467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->last ? " (last)" : "")); 8477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = LEN_; /* decode codes */ 8487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (flush == Z_TREES) { 8497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(2); 8507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto inf_leave; 8517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 8527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 8537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 2: /* dynamic block */ 8547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: dynamic codes block%s\n", 8557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->last ? " (last)" : "")); 8567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = TABLE; 8577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 8587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case 3: 8597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"invalid block type"; 8607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 8617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 8627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(2); 8637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 8647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case STORED: 8657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel BYTEBITS(); /* go to byte boundary */ 8667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(32); 8677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { 8687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"invalid stored block lengths"; 8697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 8707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 8717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 8727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->length = (unsigned)hold & 0xffff; 8737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: stored length %u\n", 8747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->length)); 8757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel INITBITS(); 8767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = COPY_; 8777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (flush == Z_TREES) goto inf_leave; 8787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case COPY_: 8797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = COPY; 8807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case COPY: 8817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy = state->length; 8827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy) { 8837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy > have) copy = have; 8847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy > left) copy = left; 8857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy == 0) goto inf_leave; 8867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel zmemcpy(put, next, copy); 8877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel have -= copy; 8887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next += copy; 8897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel left -= copy; 8907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel put += copy; 8917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->length -= copy; 8927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 8937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 8947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: stored end\n")); 8957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = TYPE; 8967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 8977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case TABLE: 8987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(14); 8997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->nlen = BITS(5) + 257; 9007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(5); 9017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->ndist = BITS(5) + 1; 9027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(5); 9037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->ncode = BITS(4) + 4; 9047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(4); 9057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifndef PKZIP_BUG_WORKAROUND 9067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->nlen > 286 || state->ndist > 30) { 9077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"too many length or distance symbols"; 9087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 9097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 9107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 9127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: table sizes ok\n")); 9137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->have = 0; 9147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = LENLENS; 9157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case LENLENS: 9167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (state->have < state->ncode) { 9177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(3); 9187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->lens[order[state->have++]] = (unsigned short)BITS(3); 9197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(3); 9207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (state->have < 19) 9227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->lens[order[state->have++]] = 0; 9237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->next = state->codes; 9247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->lencode = (const code FAR *)(state->next); 9257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->lenbits = 7; 9267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ret = inflate_table(CODES, state->lens, 19, &(state->next), 9277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel &(state->lenbits), state->work); 9287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (ret) { 9297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"invalid code lengths set"; 9307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 9317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 9327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: code lengths ok\n")); 9347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->have = 0; 9357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = CODELENS; 9367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case CODELENS: 9377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (state->have < state->nlen + state->ndist) { 9387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (;;) { 9397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel here = state->lencode[BITS(state->lenbits)]; 9407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((unsigned)(here.bits) <= bits) break; 9417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PULLBYTE(); 9427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (here.val < 16) { 9447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(here.bits); 9457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->lens[state->have++] = here.val; 9467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 9487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (here.val == 16) { 9497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(here.bits + 2); 9507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(here.bits); 9517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->have == 0) { 9527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"invalid bit length repeat"; 9537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 9547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 9557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel len = state->lens[state->have - 1]; 9577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy = 3 + BITS(2); 9587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(2); 9597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (here.val == 17) { 9617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(here.bits + 3); 9627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(here.bits); 9637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel len = 0; 9647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy = 3 + BITS(3); 9657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(3); 9667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { 9687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(here.bits + 7); 9697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(here.bits); 9707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel len = 0; 9717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy = 11 + BITS(7); 9727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(7); 9737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->have + copy > state->nlen + state->ndist) { 9757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"invalid bit length repeat"; 9767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 9777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 9787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (copy--) 9807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->lens[state->have++] = (unsigned short)len; 9817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 9847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* handle error breaks in while */ 9857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->mode == BAD) break; 9867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 9877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* check for end-of-block code (better have one) */ 9887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->lens[256] == 0) { 9897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"invalid code -- missing end-of-block"; 9907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 9917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 9927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 9937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 9947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* build code tables -- note: do not change the lenbits or distbits 9957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel values here (9 and 6) without reading the comments in inftrees.h 9967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel concerning the ENOUGH constants, which depend on those values */ 9977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->next = state->codes; 9987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->lencode = (const code FAR *)(state->next); 9997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->lenbits = 9; 10007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), 10017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel &(state->lenbits), state->work); 10027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (ret) { 10037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"invalid literal/lengths set"; 10047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 10057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 10067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->distcode = (const code FAR *)(state->next); 10087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->distbits = 6; 10097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, 10107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel &(state->next), &(state->distbits), state->work); 10117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (ret) { 10127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"invalid distances set"; 10137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 10147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 10157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: codes ok\n")); 10177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = LEN_; 10187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (flush == Z_TREES) goto inf_leave; 10197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case LEN_: 10207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = LEN; 10217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case LEN: 10227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (have >= 6 && left >= 258) { 10237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel RESTORE(); 10247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel inflate_fast(strm, out); 10257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel LOAD(); 10267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->mode == TYPE) 10277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->back = -1; 10287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 10297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->back = 0; 10317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (;;) { 10327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel here = state->lencode[BITS(state->lenbits)]; 10337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((unsigned)(here.bits) <= bits) break; 10347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PULLBYTE(); 10357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (here.op && (here.op & 0xf0) == 0) { 10377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel last = here; 10387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (;;) { 10397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel here = state->lencode[last.val + 10407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (BITS(last.bits + last.op) >> last.bits)]; 10417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((unsigned)(last.bits + here.bits) <= bits) break; 10427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PULLBYTE(); 10437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(last.bits); 10457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->back += last.bits; 10467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(here.bits); 10487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->back += here.bits; 10497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->length = (unsigned)here.val; 10507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((int)(here.op) == 0) { 10517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 10527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "inflate: literal '%c'\n" : 10537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel "inflate: literal 0x%02x\n", here.val)); 10547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = LIT; 10557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 10567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (here.op & 32) { 10587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracevv((stderr, "inflate: end of block\n")); 10597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->back = -1; 10607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = TYPE; 10617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 10627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (here.op & 64) { 10647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"invalid literal/length code"; 10657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 10667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 10677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->extra = (unsigned)(here.op) & 15; 10697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = LENEXT; 10707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case LENEXT: 10717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->extra) { 10727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(state->extra); 10737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->length += BITS(state->extra); 10747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(state->extra); 10757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->back += state->extra; 10767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracevv((stderr, "inflate: length %u\n", state->length)); 10787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->was = state->length; 10797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = DIST; 10807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case DIST: 10817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (;;) { 10827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel here = state->distcode[BITS(state->distbits)]; 10837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((unsigned)(here.bits) <= bits) break; 10847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PULLBYTE(); 10857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((here.op & 0xf0) == 0) { 10877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel last = here; 10887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel for (;;) { 10897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel here = state->distcode[last.val + 10907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (BITS(last.bits + last.op) >> last.bits)]; 10917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((unsigned)(last.bits + here.bits) <= bits) break; 10927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel PULLBYTE(); 10937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(last.bits); 10957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->back += last.bits; 10967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 10977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(here.bits); 10987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->back += here.bits; 10997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (here.op & 64) { 11007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"invalid distance code"; 11017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 11027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 11037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->offset = (unsigned)here.val; 11057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->extra = (unsigned)(here.op) & 15; 11067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = DISTEXT; 11077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case DISTEXT: 11087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->extra) { 11097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(state->extra); 11107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->offset += BITS(state->extra); 11117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel DROPBITS(state->extra); 11127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->back += state->extra; 11137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef INFLATE_STRICT 11157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->offset > state->dmax) { 11167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"invalid distance too far back"; 11177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 11187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 11197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 11217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracevv((stderr, "inflate: distance %u\n", state->offset)); 11227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = MATCH; 11237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case MATCH: 11247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (left == 0) goto inf_leave; 11257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy = out - left; 11267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->offset > copy) { /* copy from window */ 11277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy = state->offset - copy; 11287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy > state->whave) { 11297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->sane) { 11307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"invalid distance too far back"; 11317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 11327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 11337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 11357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Trace((stderr, "inflate.c too far\n")); 11367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy -= state->whave; 11377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy > state->length) copy = state->length; 11387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy > left) copy = left; 11397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel left -= copy; 11407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->length -= copy; 11417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel do { 11427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *put++ = 0; 11437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } while (--copy); 11447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->length == 0) state->mode = LEN; 11457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 11467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 11477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy > state->wnext) { 11497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy -= state->wnext; 11507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel from = state->window + (state->wsize - copy); 11517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else 11537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel from = state->window + (state->wnext - copy); 11547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy > state->length) copy = state->length; 11557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else { /* copy from output */ 11577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel from = put - state->offset; 11587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy = state->length; 11597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy > left) copy = left; 11617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel left -= copy; 11627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->length -= copy; 11637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel do { 11647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *put++ = *from++; 11657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } while (--copy); 11667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->length == 0) state->mode = LEN; 11677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 11687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case LIT: 11697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (left == 0) goto inf_leave; 11707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *put++ = (unsigned char)(state->length); 11717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel left--; 11727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = LEN; 11737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 11747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case CHECK: 11757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->wrap) { 11767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(32); 11777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel out -= left; 11787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->total_out += out; 11797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->total += out; 11807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (out) 11817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->adler = state->check = 11827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel UPDATE(state->check, put - out, out); 11837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel out = left; 11847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (( 11857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP 11867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->flags ? hold : 11877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 11887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ZSWAP32(hold)) != state->check) { 11897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"incorrect data check"; 11907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 11917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 11927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel INITBITS(); 11947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: check matches trailer\n")); 11957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 11967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef GUNZIP 11977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = LENGTH; 11987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case LENGTH: 11997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->wrap && state->flags) { 12007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel NEEDBITS(32); 12017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (hold != (state->total & 0xffffffffUL)) { 12027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->msg = (char *)"incorrect length check"; 12037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = BAD; 12047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel break; 12057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 12067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel INITBITS(); 12077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: length matches trailer\n")); 12087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 12097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 12107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = DONE; 12117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case DONE: 12127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ret = Z_STREAM_END; 12137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto inf_leave; 12147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case BAD: 12157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ret = Z_DATA_ERROR; 12167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel goto inf_leave; 12177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case MEM: 12187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_MEM_ERROR; 12197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel case SYNC: 12207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel default: 12217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_STREAM_ERROR; 12227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 12237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* 12257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Return from inflate(), updating the total counts and the check value. 12267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel If there was no progress during the inflate() call, return a buffer 12277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel error. Call updatewindow() to create and/or update the window state. 12287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Note: a memory error from inflate() is non-recoverable. 12297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 12307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel inf_leave: 12317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel RESTORE(); 12327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->wsize || (out != strm->avail_out && state->mode < BAD && 12337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (state->mode < CHECK || flush != Z_FINISH))) 12347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { 12357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = MEM; 12367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_MEM_ERROR; 12377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 12387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel in -= strm->avail_in; 12397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel out -= strm->avail_out; 12407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->total_in += in; 12417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->total_out += out; 12427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->total += out; 12437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->wrap && out) 12447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->adler = state->check = 12457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel UPDATE(state->check, strm->next_out - out, out); 12467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->data_type = state->bits + (state->last ? 64 : 0) + 12477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (state->mode == TYPE ? 128 : 0) + 12487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); 12497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) 12507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ret = Z_BUF_ERROR; 12517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return ret; 12527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 12537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateEnd(strm) 12557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 12567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 12577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 12587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) 12597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_STREAM_ERROR; 12607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 12617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->window != Z_NULL) ZFREE(strm, state->window); 12627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ZFREE(strm, strm->state); 12637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->state = Z_NULL; 12647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: end\n")); 12657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_OK; 12667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 12677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) 12697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 12707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielBytef *dictionary; 12717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieluInt *dictLength; 12727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 12737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 12747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* check state */ 12767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 12777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 12787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* copy dictionary */ 12807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->whave && dictionary != Z_NULL) { 12817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel zmemcpy(dictionary, state->window + state->wnext, 12827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->whave - state->wnext); 12837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel zmemcpy(dictionary + state->whave - state->wnext, 12847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->window, state->wnext); 12857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 12867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (dictLength != Z_NULL) 12877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *dictLength = state->whave; 12887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_OK; 12897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 12907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 12917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) 12927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 12937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconst Bytef *dictionary; 12947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanieluInt dictLength; 12957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 12967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 12977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned long dictid; 12987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel int ret; 12997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* check state */ 13017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 13027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 13037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->wrap != 0 && state->mode != DICT) 13047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_STREAM_ERROR; 13057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* check for correct dictionary identifier */ 13077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->mode == DICT) { 13087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel dictid = adler32(0L, Z_NULL, 0); 13097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel dictid = adler32(dictid, dictionary, dictLength); 13107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (dictid != state->check) 13117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_DATA_ERROR; 13127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* copy dictionary to window using updatewindow(), which will amend the 13157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel existing dictionary if appropriate */ 13167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ret = updatewindow(strm, dictionary + dictLength, dictLength); 13177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (ret) { 13187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = MEM; 13197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_MEM_ERROR; 13207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->havedict = 1; 13227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Tracev((stderr, "inflate: dictionary set\n")); 13237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_OK; 13247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 13257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateGetHeader(strm, head) 13277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 13287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielgz_headerp head; 13297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 13307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 13317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* check state */ 13337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 13347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 13357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; 13367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* save header structure */ 13387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->head = head; 13397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel head->done = 0; 13407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_OK; 13417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 13427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* 13447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found 13457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel or when out of input. When called, *have is the number of pattern bytes 13467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel found in order so far, in 0..3. On return *have is updated to the new 13477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state. If on return *have equals four, then the pattern was found and the 13487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return value is how many bytes were read including the last byte of the 13497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel pattern. If *have is less than four, then the pattern has not been found 13507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel yet and the return value is len. In the latter case, syncsearch() can be 13517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel called again with more data and the *have state. *have is initialized to 13527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel zero for the first call. 13537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 13547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellocal unsigned syncsearch(have, buf, len) 13557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielunsigned FAR *have; 13567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielconst unsigned char FAR *buf; 13577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielunsigned len; 13587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 13597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned got; 13607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned next; 13617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel got = *have; 13637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next = 0; 13647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (next < len && got < 4) { 13657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) 13667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel got++; 13677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else if (buf[next]) 13687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel got = 0; 13697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel else 13707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel got = 4 - got; 13717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel next++; 13727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 13737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel *have = got; 13747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return next; 13757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 13767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateSync(strm) 13787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 13797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 13807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned len; /* number of bytes to look at or looked at */ 13817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned long in, out; /* temporary to save total_in and total_out */ 13827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned char buf[4]; /* to restore bit buffer to byte string */ 13837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 13847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* check parameters */ 13867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 13877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 13887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; 13897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 13907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* if first time, start search in bit buffer */ 13917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->mode != SYNC) { 13927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = SYNC; 13937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->hold <<= state->bits & 7; 13947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->bits -= state->bits & 7; 13957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel len = 0; 13967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel while (state->bits >= 8) { 13977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel buf[len++] = (unsigned char)(state->hold); 13987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->hold >>= 8; 13997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->bits -= 8; 14007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->have = 0; 14027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel syncsearch(&(state->have), buf, len); 14037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* search available input */ 14067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel len = syncsearch(&(state->have), strm->next_in, strm->avail_in); 14077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->avail_in -= len; 14087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->next_in += len; 14097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->total_in += len; 14107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* return no joy or set up to restart inflate() on a new block */ 14127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->have != 4) return Z_DATA_ERROR; 14137eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel in = strm->total_in; out = strm->total_out; 14147eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel inflateReset(strm); 14157eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel strm->total_in = in; strm->total_out = out; 14167eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->mode = TYPE; 14177eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_OK; 14187eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 14197eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14207eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel/* 14217eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Returns true if inflate is currently at the end of a block generated by 14227eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP 14237eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel implementation to provide an additional safety check. PPP uses 14247eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored 14257eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel block. When decompressing, PPP checks that at the end of input packet, 14267eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel inflate is waiting for these length bytes. 14277eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel */ 14287eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateSyncPoint(strm) 14297eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 14307eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 14317eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 14327eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14337eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 14347eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 14357eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return state->mode == STORED && state->bits == 0; 14367eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 14377eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14387eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateCopy(dest, source) 14397eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp dest; 14407eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp source; 14417eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 14427eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 14437eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *copy; 14447eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned char FAR *window; 14457eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel unsigned wsize; 14467eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14477eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* check input */ 14487eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || 14497eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) 14507eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_STREAM_ERROR; 14517eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)source->state; 14527eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14537eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* allocate space */ 14547eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy = (struct inflate_state FAR *) 14557eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ZALLOC(source, 1, sizeof(struct inflate_state)); 14567eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (copy == Z_NULL) return Z_MEM_ERROR; 14577eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel window = Z_NULL; 14587eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->window != Z_NULL) { 14597eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel window = (unsigned char FAR *) 14607eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); 14617eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (window == Z_NULL) { 14627eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel ZFREE(source, copy); 14637eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_MEM_ERROR; 14647eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14657eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14667eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14677eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel /* copy state */ 14687eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); 14697eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); 14707eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (state->lencode >= state->codes && 14717eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->lencode <= state->codes + ENOUGH - 1) { 14727eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy->lencode = copy->codes + (state->lencode - state->codes); 14737eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy->distcode = copy->codes + (state->distcode - state->codes); 14747eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14757eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy->next = copy->codes + (state->next - state->codes); 14767eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (window != Z_NULL) { 14777eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel wsize = 1U << state->wbits; 14787eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel zmemcpy(window, state->window, wsize); 14797eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel } 14807eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel copy->window = window; 14817eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel dest->state = (struct internal_state FAR *)copy; 14827eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_OK; 14837eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 14847eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14857eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint ZEXPORT inflateUndermine(strm, subvert) 14867eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 14877eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielint subvert; 14887eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 14897eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 14907eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 14917eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 14927eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 14937eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->sane = !subvert; 14947eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 14957eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_OK; 14967eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#else 14977eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state->sane = 1; 14987eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return Z_DATA_ERROR; 14997eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel#endif 15007eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 15017eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 15027eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniellong ZEXPORT inflateMark(strm) 15037eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDanielz_streamp strm; 15047eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel{ 15057eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel struct inflate_state FAR *state; 15067eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel 15077eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; 15087eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel state = (struct inflate_state FAR *)strm->state; 15097eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel return ((long)(state->back) << 16) + 15107eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (state->mode == COPY ? state->length : 15117eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel (state->mode == MATCH ? state->was - state->length : 0)); 15127eb75bccb5dacb658c63db1a9a980950c3d54d42Daryl McDaniel} 1513