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