1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* inflate.c -- zlib decompression 2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Copyright (C) 1995-2012 Mark Adler 3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * For conditions of distribution and use, see copyright notice in zlib.h 4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Change history: 8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1.2.beta0 24 Nov 2002 10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - First version -- complete rewrite of inflate to simplify code, avoid 11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * creation of window when not needed, minimize use of window when it is 12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * needed, make inffast.c even faster, implement gzip decoding, and to 13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * improve code readability and style over the previous zlib inflate code 14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1.2.beta1 25 Nov 2002 16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Use pointers for available input and output checking in inffast.c 17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Remove input and output counters in inffast.c 18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Remove unnecessary second byte pull from length extra in inffast.c 20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Unroll direct copy to three copies per loop in inffast.c 21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1.2.beta2 4 Dec 2002 23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Change external routine names to reduce potential conflicts 24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Correct filename to inffixed.h for fixed tables in inflate.c 25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Make hbuf[] unsigned char to match parameter type in inflate.c 26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) 27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * to avoid negation problem on Alphas (64 bit) in inflate.c 28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1.2.beta3 22 Dec 2002 30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Add comments on state->bits assertion in inffast.c 31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Add comments on op field in inftrees.h 32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Fix bug in reuse of allocated window after inflateReset() 33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Remove bit fields--back to byte structure for speed 34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths 35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Change post-increments to pre-increments in inflate_fast(), PPC biased? 36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Add compile time option, POSTINC, to use post-increments instead (Intel?) 37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Make MATCH copy in inflate() much faster for when inflate_fast() not used 38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Use local copies of stream next and avail values, as well as local bit 39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * buffer and bit count in inflate()--for speed when inflate_fast() not used 40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1.2.beta4 1 Jan 2003 42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings 43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Move a comment on output buffer sizes from inffast.c to inflate.c 44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Add comments in inffast.c to introduce the inflate_fast() routine 45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Rearrange window copies in inflate_fast() for speed and simplification 46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Unroll last copy for window match in inflate_fast() 47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Use local copies of window variables in inflate_fast() for speed 48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Pull out common wnext == 0 case for speed in inflate_fast() 49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Make op and len in inflate_fast() unsigned for consistency 50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Add FAR to lcode and dcode declarations in inflate_fast() 51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Simplified bad distance check in inflate_fast() 52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new 53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * source file infback.c to provide a call-back interface to inflate for 54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * programs like gzip and unzip -- uses window as output buffer to avoid 55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * window copying 56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1.2.beta5 1 Jan 2003 58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Improved inflateBack() interface to allow the caller to provide initial 59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * input in strm. 60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Fixed stored blocks bug in inflateBack() 61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1.2.beta6 4 Jan 2003 63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Added comments in inffast.c on effectiveness of POSTINC 64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Typecasting all around to reduce compiler warnings 65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Changed loops from while (1) or do {} while (1) to for (;;), again to 66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * make compilers happy 67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Changed type of window in inflateBackInit() to unsigned char * 68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1.2.beta7 27 Jan 2003 70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Changed many types to unsigned or unsigned short to avoid warnings 71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Added inflateCopy() function 72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1.2.0 9 Mar 2003 74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Changed inflateBack() interface to provide separate opaque descriptors 75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * for the in() and out() functions 76793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Changed inflateBack() argument and in_func typedef to swap the length 77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * and buffer address return values for the input function 78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * - Check next_in and next_out for Z_NULL on entry to inflate() 79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. 81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "zutil.h" 84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "inftrees.h" 85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "inflate.h" 86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "inffast.h" 87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef MAKEFIXED 89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# ifndef BUILDFIXED 90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# define BUILDFIXED 91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# endif 92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* function prototypes */ 95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerlocal void fixedtables OF((struct inflate_state FAR *state)); 96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerlocal int updatewindow OF((z_streamp strm, const unsigned char FAR *end, 97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned copy)); 98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef BUILDFIXED 99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler void makefixed OF((void)); 100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerlocal unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, 102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned len)); 103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateResetKeep(strm) 105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->total_in = strm->total_out = state->total = 0; 112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = Z_NULL; 113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->wrap) /* to support ill-conceived Java test suite */ 114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->adler = state->wrap & 1; 115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = HEAD; 116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->last = 0; 117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->havedict = 0; 118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->dmax = 32768U; 119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head = Z_NULL; 120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->hold = 0; 121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->bits = 0; 122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lencode = state->distcode = state->next = state->codes; 123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->sane = 1; 124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->back = -1; 125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: reset\n")); 126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_OK; 127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateReset(strm) 130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->wsize = 0; 137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->whave = 0; 138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->wnext = 0; 139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return inflateResetKeep(strm); 140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateReset2(strm, windowBits) 143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint windowBits; 145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int wrap; 147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* get the state */ 150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* extract wrap request from windowBits parameter */ 154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (windowBits < 0) { 155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler wrap = 0; 156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler windowBits = -windowBits; 157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { 159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler wrap = (windowBits >> 4) + 1; 160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef GUNZIP 161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (windowBits < 48) 162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler windowBits &= 15; 163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* set number of window bits, free window if different */ 167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (windowBits && (windowBits < 8 || windowBits > 15)) 168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_STREAM_ERROR; 169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { 170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ZFREE(strm, state->window); 171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->window = Z_NULL; 172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* update state and reset the rest of it */ 175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->wrap = wrap; 176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->wbits = (unsigned)windowBits; 177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return inflateReset(strm); 178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) 181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint windowBits; 183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerconst char *version; 184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint stream_size; 185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int ret; 187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler stream_size != (int)(sizeof(z_stream))) 191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_VERSION_ERROR; 192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL) return Z_STREAM_ERROR; 193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = Z_NULL; /* in case we return an error */ 194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm->zalloc == (alloc_func)0) { 195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef Z_SOLO 196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_STREAM_ERROR; 197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#else 198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->zalloc = zcalloc; 199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->opaque = (voidpf)0; 200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm->zfree == (free_func)0) 203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef Z_SOLO 204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_STREAM_ERROR; 205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#else 206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->zfree = zcfree; 207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *) 209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ZALLOC(strm, 1, sizeof(struct inflate_state)); 210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state == Z_NULL) return Z_MEM_ERROR; 211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: allocated\n")); 212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->state = (struct internal_state FAR *)state; 213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->window = Z_NULL; 214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = inflateReset2(strm, windowBits); 215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (ret != Z_OK) { 216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ZFREE(strm, state); 217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->state = Z_NULL; 218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return ret; 220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateInit_(strm, version, stream_size) 223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerconst char *version; 225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint stream_size; 226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return inflateInit2_(strm, DEF_WBITS, version, stream_size); 228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflatePrime(strm, bits, value) 231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint bits; 233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint value; 234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (bits < 0) { 240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->hold = 0; 241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->bits = 0; 242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_OK; 243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; 245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler value &= (1L << bits) - 1; 246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->hold += value << state->bits; 247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->bits += bits; 248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_OK; 249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Return state with length and distance decoding tables and index sizes set to 253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fixed code decoding. Normally this returns fixed tables from inffixed.h. 254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler If BUILDFIXED is defined, then instead this routine builds the tables the 255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler first time it's called, and returns those tables the first time and 256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler thereafter. This reduces the size of the code by about 2K bytes, in 257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler exchange for a little execution time. However, BUILDFIXED should not be 258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler used for threaded applications, since the rewriting of the tables and virgin 259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler may not be thread-safe. 260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerlocal void fixedtables(state) 262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstruct inflate_state FAR *state; 263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef BUILDFIXED 265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static int virgin = 1; 266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static code *lenfix, *distfix; 267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static code fixed[544]; 268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* build fixed huffman tables if first call (may not be thread safe) */ 270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (virgin) { 271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned sym, bits; 272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static code *next; 273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* literal/length table */ 275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sym = 0; 276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (sym < 144) state->lens[sym++] = 8; 277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (sym < 256) state->lens[sym++] = 9; 278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (sym < 280) state->lens[sym++] = 7; 279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (sym < 288) state->lens[sym++] = 8; 280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next = fixed; 281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler lenfix = next; 282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits = 9; 283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); 284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* distance table */ 286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sym = 0; 287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (sym < 32) state->lens[sym++] = 5; 288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler distfix = next; 289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits = 5; 290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); 291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* do this just once */ 293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler virgin = 0; 294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#else /* !BUILDFIXED */ 296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# include "inffixed.h" 297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif /* BUILDFIXED */ 298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lencode = lenfix; 299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lenbits = 9; 300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->distcode = distfix; 301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->distbits = 5; 302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef MAKEFIXED 305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <stdio.h> 306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also 309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler defines BUILDFIXED, so the tables are built on the fly. makefixed() writes 310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler those tables to stdout, which would be piped to inffixed.h. A small program 311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler can simply call makefixed to do this: 312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler void makefixed(void); 314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int main(void) 316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler { 317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler makefixed(); 318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Then that can be linked with zlib built with MAKEFIXED defined and run: 322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler a.out > inffixed.h 324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid makefixed() 326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned low, size; 328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state state; 329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fixedtables(&state); 331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler puts(" /* inffixed.h -- table for decoding fixed codes"); 332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler puts(" * Generated automatically by makefixed()."); 333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler puts(" */"); 334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler puts(""); 335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler puts(" /* WARNING: this file should *not* be used by applications."); 336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler puts(" It is part of the implementation of this library and is"); 337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler puts(" subject to change. Applications should only use zlib.h."); 338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler puts(" */"); 339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler puts(""); 340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler size = 1U << 9; 341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler printf(" static const code lenfix[%u] = {", size); 342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler low = 0; 343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) { 344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((low % 7) == 0) printf("\n "); 345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, 346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state.lencode[low].bits, state.lencode[low].val); 347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (++low == size) break; 348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler putchar(','); 349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler puts("\n };"); 351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler size = 1U << 5; 352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler printf("\n static const code distfix[%u] = {", size); 353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler low = 0; 354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) { 355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((low % 6) == 0) printf("\n "); 356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, 357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state.distcode[low].val); 358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (++low == size) break; 359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler putchar(','); 360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler puts("\n };"); 362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif /* MAKEFIXED */ 364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Update the window with the last wsize (normally 32K) bytes written before 367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler returning. If window does not exist yet, create it. This is only called 368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler when a window is already in use, or when output has been written during this 369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflate call, but the end of the deflate stream has not been reached yet. 370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler It is also called to create a window for dictionary data when a dictionary 371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler is loaded. 372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Providing output buffers larger than 32K to inflate() should provide a speed 374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler advantage, since only the last 32K of output is copied to the sliding window 375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler upon return from inflate(), and since all distances after the first 32K of 376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler output will fall in the output data, making match copies simpler and faster. 377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler The advantage may be dependent on the size of the processor's data caches. 378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerlocal int updatewindow(strm, end, copy) 380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerconst Bytef *end; 382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerunsigned copy; 383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned dist; 386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* if it hasn't been done already, allocate space for the window */ 390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->window == Z_NULL) { 391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->window = (unsigned char FAR *) 392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ZALLOC(strm, 1U << state->wbits, 393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler sizeof(unsigned char)); 394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->window == Z_NULL) return 1; 395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* if window not in use yet, initialize */ 398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->wsize == 0) { 399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->wsize = 1U << state->wbits; 400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->wnext = 0; 401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->whave = 0; 402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 404793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* copy state->wsize or less output bytes into the circular window */ 405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy >= state->wsize) { 406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler zmemcpy(state->window, end - state->wsize, state->wsize); 407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->wnext = 0; 408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->whave = state->wsize; 409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { 411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dist = state->wsize - state->wnext; 412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (dist > copy) dist = copy; 413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler zmemcpy(state->window + state->wnext, end - copy, dist); 414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy -= dist; 415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy) { 416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler zmemcpy(state->window, end - copy, copy); 417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->wnext = copy; 418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->whave = state->wsize; 419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { 421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->wnext += dist; 422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->wnext == state->wsize) state->wnext = 0; 423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->whave < state->wsize) state->whave += dist; 424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return 0; 427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Macros for inflate(): */ 430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* check function to use adler32() for zlib or crc32() for gzip */ 432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef GUNZIP 433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# define UPDATE(check, buf, len) \ 434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) 435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#else 436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# define UPDATE(check, buf, len) adler32(check, buf, len) 437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* check macros for header crc */ 440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef GUNZIP 441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# define CRC2(check, word) \ 442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hbuf[0] = (unsigned char)(word); \ 444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hbuf[1] = (unsigned char)((word) >> 8); \ 445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler check = crc32(check, hbuf, 2); \ 446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler# define CRC4(check, word) \ 449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hbuf[0] = (unsigned char)(word); \ 451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hbuf[1] = (unsigned char)((word) >> 8); \ 452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hbuf[2] = (unsigned char)((word) >> 16); \ 453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hbuf[3] = (unsigned char)((word) >> 24); \ 454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler check = crc32(check, hbuf, 4); \ 455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Load registers with state in inflate() for speed */ 459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define LOAD() \ 460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler put = strm->next_out; \ 462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left = strm->avail_out; \ 463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next = strm->next_in; \ 464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler have = strm->avail_in; \ 465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hold = state->hold; \ 466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits = state->bits; \ 467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Restore state from registers in inflate() */ 470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define RESTORE() \ 471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->next_out = put; \ 473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->avail_out = left; \ 474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->next_in = next; \ 475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->avail_in = have; \ 476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->hold = hold; \ 477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->bits = bits; \ 478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Clear the input bit accumulator */ 481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define INITBITS() \ 482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hold = 0; \ 484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits = 0; \ 485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Get a byte of input into the bit accumulator, or return from inflate() 488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if there is no input available. */ 489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define PULLBYTE() \ 490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (have == 0) goto inf_leave; \ 492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler have--; \ 493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hold += (unsigned long)(*next++) << bits; \ 494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits += 8; \ 495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Assure that there are at least n bits in the bit accumulator. If there is 498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler not enough available input to do that, then return from inflate(). */ 499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define NEEDBITS(n) \ 500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (bits < (unsigned)(n)) \ 502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULLBYTE(); \ 503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Return the low n bits of the bit accumulator (n < 16) */ 506793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define BITS(n) \ 507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ((unsigned)hold & ((1U << (n)) - 1)) 508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Remove n bits from the bit accumulator */ 510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define DROPBITS(n) \ 511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hold >>= (n); \ 513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits -= (unsigned)(n); \ 514793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* Remove zero to seven bits as needed to go to a byte boundary */ 517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define BYTEBITS() \ 518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { \ 519793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler hold >>= bits & 7; \ 520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler bits -= bits & 7; \ 521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (0) 522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflate() uses a state machine to process as much input data and generate as 525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler much output data as possible before returning. The state machine is 526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler structured roughly as follows: 527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) switch (state) { 529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ... 530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case STATEn: 531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (not enough input data or output space to make progress) 532793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return; 533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ... make progress ... 534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = STATEm; 535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ... 537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler so when inflate() is called again, the same case is attempted again, and 540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if the appropriate resources are provided, the machine proceeds to the 541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next state. The NEEDBITS() macro is usually the way the state evaluates 542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler whether it can proceed or should return. NEEDBITS() does the return if 543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler the requested bits are not available. The typical use of the BITS macros 544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler is: 545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(n); 547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ... do something with BITS(n) ... 548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(n); 549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler where NEEDBITS(n) either returns from inflate() if there isn't enough 551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler input left to load n bits into the accumulator, or it continues. BITS(n) 552793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler gives the low n bits in the accumulator. When done, DROPBITS(n) drops 553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler the low n bits off the accumulator. INITBITS() clears the accumulator 554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler and sets the number of available bits to zero. BYTEBITS() discards just 555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler enough bits to put the accumulator on a byte boundary. After BYTEBITS() 556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. 557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return 559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if there is no input available. The decoding of variable length codes uses 560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULLBYTE() directly in order to pull just enough bytes to decode the next 561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler code, and no more. 562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Some states loop until they get enough input, making sure that enough 564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state information is maintained to continue the loop where it left off 565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if NEEDBITS() returns in the loop. For example, want, need, and keep 566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler would all have to actually be part of the saved state in case NEEDBITS() 567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler returns: 568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case STATEw: 570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (want < need) { 571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(n); 572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler keep[want++] = BITS(n); 573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(n); 574793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = STATEx; 576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case STATEx: 577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler As shown above, if the next state is also the next case, then the break 579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler is omitted. 580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler A state may also return if there is not enough output space available to 582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler complete that state. Those states are copying stored data, writing a 583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler literal byte, and copying a matching string. 584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler When returning, a "goto inf_leave" is used to update the total counters, 586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler update the check value, and determine whether any progress has been made 587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler during that inflate() call in order to return the proper return code. 588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Progress is defined as a change in either strm->avail_in or strm->avail_out. 589793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler When there is a window, goto inf_leave will update the window with the last 590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler output written. If a goto inf_leave occurs in the middle of decompression 591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler and there is no window currently, goto inf_leave will create one and copy 592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler output to the window for the next call of inflate(). 593793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler In this implementation, the flush parameter of inflate() only affects the 595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return code (per zlib.h). inflate() always writes as much as possible to 596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->next_out, given the space available and the provided input--the effect 597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers 598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler the allocation of and copying into a sliding window until necessary, which 599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler provides the effect documented in zlib.h for Z_FINISH when the entire input 600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler stream available. So the only thing the flush parameter actually does is: 601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it 602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler will return Z_BUF_ERROR if it has not reached the end of the stream. 603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflate(strm, flush) 606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint flush; 608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler z_const unsigned char FAR *next; /* next input */ 611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char FAR *put; /* next output */ 612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned have, left; /* available input and output */ 613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned long hold; /* bit buffer */ 614793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned bits; /* bits in bit buffer */ 615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned in, out; /* save starting available input and output */ 616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned copy; /* number of stored or match bytes to copy */ 617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char FAR *from; /* where to copy match bytes from */ 618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler code here; /* current decoding table entry */ 619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler code last; /* parent table entry */ 620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned len; /* length to copy for repeats, bits to drop */ 621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int ret; /* return code */ 622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef GUNZIP 623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ 624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler static const unsigned short order[19] = /* permutation of code lengths */ 626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || 629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (strm->next_in == Z_NULL && strm->avail_in != 0)) 630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_STREAM_ERROR; 631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ 634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler LOAD(); 635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler in = have; 636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler out = left; 637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = Z_OK; 638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) 639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (state->mode) { 640793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case HEAD: 641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->wrap == 0) { 642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = TYPEDO; 643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(16); 646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef GUNZIP 647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ 648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->check = crc32(0L, Z_NULL, 0); 649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler CRC2(state->check, hold); 650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler INITBITS(); 651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = FLAGS; 652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->flags = 0; /* expect zlib header */ 655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->head != Z_NULL) 656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->done = -1; 657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (!(state->wrap & 1) || /* check if zlib header allowed */ 658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#else 659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ( 660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ((BITS(8) << 8) + (hold >> 8)) % 31) { 662793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"incorrect header check"; 663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (BITS(4) != Z_DEFLATED) { 667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"unknown compression method"; 668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(4); 672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler len = BITS(4) + 8; 673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->wbits == 0) 674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->wbits = len; 675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (len > state->wbits) { 676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid window size"; 677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 678793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->dmax = 1U << len; 681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: zlib header ok\n")); 682793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->adler = state->check = adler32(0L, Z_NULL, 0); 683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = hold & 0x200 ? DICTID : TYPE; 684793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler INITBITS(); 685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef GUNZIP 687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case FLAGS: 688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(16); 689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->flags = (int)(hold); 690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((state->flags & 0xff) != Z_DEFLATED) { 691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"unknown compression method"; 692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->flags & 0xe000) { 696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"unknown header flags set"; 697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->head != Z_NULL) 701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->text = (int)((hold >> 8) & 1); 702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->flags & 0x0200) CRC2(state->check, hold); 703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler INITBITS(); 704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = TIME; 705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case TIME: 706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(32); 707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->head != Z_NULL) 708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->time = hold; 709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->flags & 0x0200) CRC4(state->check, hold); 710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler INITBITS(); 711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = OS; 712793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case OS: 713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(16); 714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->head != Z_NULL) { 715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->xflags = (int)(hold & 0xff); 716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->os = (int)(hold >> 8); 717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->flags & 0x0200) CRC2(state->check, hold); 719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler INITBITS(); 720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = EXLEN; 721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case EXLEN: 722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->flags & 0x0400) { 723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(16); 724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length = (unsigned)(hold); 725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->head != Z_NULL) 726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->extra_len = (unsigned)hold; 727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->flags & 0x0200) CRC2(state->check, hold); 728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler INITBITS(); 729793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 730793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (state->head != Z_NULL) 731793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->extra = Z_NULL; 732793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = EXTRA; 733793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case EXTRA: 734793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->flags & 0x0400) { 735793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = state->length; 736793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy > have) copy = have; 737793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy) { 738793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->head != Z_NULL && 739793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->extra != Z_NULL) { 740793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler len = state->head->extra_len - state->length; 741793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler zmemcpy(state->head->extra + len, next, 742793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler len + copy > state->head->extra_max ? 743793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->extra_max - len : copy); 744793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 745793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->flags & 0x0200) 746793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->check = crc32(state->check, next, copy); 747793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler have -= copy; 748793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next += copy; 749793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length -= copy; 750793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 751793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->length) goto inf_leave; 752793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 753793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length = 0; 754793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = NAME; 755793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case NAME: 756793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->flags & 0x0800) { 757793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (have == 0) goto inf_leave; 758793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = 0; 759793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 760793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler len = (unsigned)(next[copy++]); 761793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->head != Z_NULL && 762793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->name != Z_NULL && 763793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length < state->head->name_max) 764793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->name[state->length++] = len; 765793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (len && copy < have); 766793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->flags & 0x0200) 767793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->check = crc32(state->check, next, copy); 768793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler have -= copy; 769793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next += copy; 770793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (len) goto inf_leave; 771793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 772793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (state->head != Z_NULL) 773793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->name = Z_NULL; 774793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length = 0; 775793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = COMMENT; 776793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case COMMENT: 777793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->flags & 0x1000) { 778793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (have == 0) goto inf_leave; 779793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = 0; 780793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 781793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler len = (unsigned)(next[copy++]); 782793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->head != Z_NULL && 783793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->comment != Z_NULL && 784793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length < state->head->comm_max) 785793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->comment[state->length++] = len; 786793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (len && copy < have); 787793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->flags & 0x0200) 788793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->check = crc32(state->check, next, copy); 789793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler have -= copy; 790793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next += copy; 791793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (len) goto inf_leave; 792793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 793793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (state->head != Z_NULL) 794793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->comment = Z_NULL; 795793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = HCRC; 796793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case HCRC: 797793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->flags & 0x0200) { 798793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(16); 799793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (hold != (state->check & 0xffff)) { 800793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"header crc mismatch"; 801793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 802793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 803793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 804793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler INITBITS(); 805793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 806793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->head != Z_NULL) { 807793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->hcrc = (int)((state->flags >> 9) & 1); 808793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head->done = 1; 809793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 810793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->adler = state->check = crc32(0L, Z_NULL, 0); 811793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = TYPE; 812793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 813793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 814793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case DICTID: 815793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(32); 816793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->adler = state->check = ZSWAP32(hold); 817793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler INITBITS(); 818793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = DICT; 819793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case DICT: 820793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->havedict == 0) { 821793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler RESTORE(); 822793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_NEED_DICT; 823793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 824793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->adler = state->check = adler32(0L, Z_NULL, 0); 825793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = TYPE; 826793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case TYPE: 827793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; 828793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case TYPEDO: 829793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->last) { 830793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler BYTEBITS(); 831793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = CHECK; 832793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 833793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 834793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(3); 835793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->last = BITS(1); 836793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(1); 837793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler switch (BITS(2)) { 838793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 0: /* stored block */ 839793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: stored block%s\n", 840793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->last ? " (last)" : "")); 841793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = STORED; 842793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 843793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 1: /* fixed block */ 844793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler fixedtables(state); 845793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: fixed codes block%s\n", 846793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->last ? " (last)" : "")); 847793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = LEN_; /* decode codes */ 848793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (flush == Z_TREES) { 849793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(2); 850793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto inf_leave; 851793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 852793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 853793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 2: /* dynamic block */ 854793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: dynamic codes block%s\n", 855793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->last ? " (last)" : "")); 856793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = TABLE; 857793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 858793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case 3: 859793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid block type"; 860793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 861793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 862793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(2); 863793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 864793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case STORED: 865793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler BYTEBITS(); /* go to byte boundary */ 866793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(32); 867793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { 868793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid stored block lengths"; 869793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 870793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 871793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 872793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length = (unsigned)hold & 0xffff; 873793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: stored length %u\n", 874793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length)); 875793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler INITBITS(); 876793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = COPY_; 877793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (flush == Z_TREES) goto inf_leave; 878793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case COPY_: 879793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = COPY; 880793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case COPY: 881793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = state->length; 882793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy) { 883793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy > have) copy = have; 884793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy > left) copy = left; 885793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy == 0) goto inf_leave; 886793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler zmemcpy(put, next, copy); 887793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler have -= copy; 888793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next += copy; 889793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left -= copy; 890793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler put += copy; 891793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length -= copy; 892793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 893793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 894793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: stored end\n")); 895793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = TYPE; 896793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 897793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case TABLE: 898793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(14); 899793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->nlen = BITS(5) + 257; 900793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(5); 901793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->ndist = BITS(5) + 1; 902793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(5); 903793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->ncode = BITS(4) + 4; 904793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(4); 905793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifndef PKZIP_BUG_WORKAROUND 906793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->nlen > 286 || state->ndist > 30) { 907793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"too many length or distance symbols"; 908793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 909793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 910793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 911793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 912793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: table sizes ok\n")); 913793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->have = 0; 914793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = LENLENS; 915793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case LENLENS: 916793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (state->have < state->ncode) { 917793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(3); 918793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lens[order[state->have++]] = (unsigned short)BITS(3); 919793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(3); 920793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 921793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (state->have < 19) 922793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lens[order[state->have++]] = 0; 923793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->next = state->codes; 924793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lencode = (const code FAR *)(state->next); 925793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lenbits = 7; 926793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = inflate_table(CODES, state->lens, 19, &(state->next), 927793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler &(state->lenbits), state->work); 928793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (ret) { 929793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid code lengths set"; 930793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 931793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 932793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 933793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: code lengths ok\n")); 934793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->have = 0; 935793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = CODELENS; 936793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CODELENS: 937793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (state->have < state->nlen + state->ndist) { 938793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) { 939793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler here = state->lencode[BITS(state->lenbits)]; 940793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((unsigned)(here.bits) <= bits) break; 941793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULLBYTE(); 942793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 943793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (here.val < 16) { 944793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(here.bits); 945793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lens[state->have++] = here.val; 946793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 947793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { 948793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (here.val == 16) { 949793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(here.bits + 2); 950793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(here.bits); 951793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->have == 0) { 952793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid bit length repeat"; 953793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 954793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 955793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 956793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler len = state->lens[state->have - 1]; 957793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = 3 + BITS(2); 958793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(2); 959793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 960793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (here.val == 17) { 961793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(here.bits + 3); 962793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(here.bits); 963793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler len = 0; 964793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = 3 + BITS(3); 965793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(3); 966793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 967793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { 968793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(here.bits + 7); 969793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(here.bits); 970793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler len = 0; 971793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = 11 + BITS(7); 972793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(7); 973793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 974793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->have + copy > state->nlen + state->ndist) { 975793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid bit length repeat"; 976793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 977793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 978793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 979793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (copy--) 980793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lens[state->have++] = (unsigned short)len; 981793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 982793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 983793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 984793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* handle error breaks in while */ 985793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->mode == BAD) break; 986793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 987793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* check for end-of-block code (better have one) */ 988793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->lens[256] == 0) { 989793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid code -- missing end-of-block"; 990793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 991793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 992793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 993793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 994793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* build code tables -- note: do not change the lenbits or distbits 995793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler values here (9 and 6) without reading the comments in inftrees.h 996793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler concerning the ENOUGH constants, which depend on those values */ 997793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->next = state->codes; 998793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lencode = (const code FAR *)(state->next); 999793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lenbits = 9; 1000793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), 1001793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler &(state->lenbits), state->work); 1002793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (ret) { 1003793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid literal/lengths set"; 1004793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 1005793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1006793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1007793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->distcode = (const code FAR *)(state->next); 1008793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->distbits = 6; 1009793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, 1010793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler &(state->next), &(state->distbits), state->work); 1011793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (ret) { 1012793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid distances set"; 1013793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 1014793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1015793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1016793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: codes ok\n")); 1017793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = LEN_; 1018793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (flush == Z_TREES) goto inf_leave; 1019793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case LEN_: 1020793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = LEN; 1021793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case LEN: 1022793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (have >= 6 && left >= 258) { 1023793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler RESTORE(); 1024793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflate_fast(strm, out); 1025793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler LOAD(); 1026793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->mode == TYPE) 1027793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->back = -1; 1028793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1029793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1030793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->back = 0; 1031793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) { 1032793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler here = state->lencode[BITS(state->lenbits)]; 1033793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((unsigned)(here.bits) <= bits) break; 1034793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULLBYTE(); 1035793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1036793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (here.op && (here.op & 0xf0) == 0) { 1037793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler last = here; 1038793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) { 1039793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler here = state->lencode[last.val + 1040793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (BITS(last.bits + last.op) >> last.bits)]; 1041793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((unsigned)(last.bits + here.bits) <= bits) break; 1042793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULLBYTE(); 1043793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1044793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(last.bits); 1045793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->back += last.bits; 1046793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1047793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(here.bits); 1048793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->back += here.bits; 1049793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length = (unsigned)here.val; 1050793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((int)(here.op) == 0) { 1051793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 1052793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "inflate: literal '%c'\n" : 1053793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler "inflate: literal 0x%02x\n", here.val)); 1054793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = LIT; 1055793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1056793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1057793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (here.op & 32) { 1058793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracevv((stderr, "inflate: end of block\n")); 1059793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->back = -1; 1060793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = TYPE; 1061793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1062793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1063793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (here.op & 64) { 1064793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid literal/length code"; 1065793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 1066793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1067793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1068793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->extra = (unsigned)(here.op) & 15; 1069793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = LENEXT; 1070793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case LENEXT: 1071793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->extra) { 1072793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(state->extra); 1073793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length += BITS(state->extra); 1074793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(state->extra); 1075793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->back += state->extra; 1076793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1077793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracevv((stderr, "inflate: length %u\n", state->length)); 1078793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->was = state->length; 1079793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = DIST; 1080793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case DIST: 1081793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) { 1082793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler here = state->distcode[BITS(state->distbits)]; 1083793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((unsigned)(here.bits) <= bits) break; 1084793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULLBYTE(); 1085793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1086793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((here.op & 0xf0) == 0) { 1087793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler last = here; 1088793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler for (;;) { 1089793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler here = state->distcode[last.val + 1090793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (BITS(last.bits + last.op) >> last.bits)]; 1091793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((unsigned)(last.bits + here.bits) <= bits) break; 1092793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler PULLBYTE(); 1093793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1094793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(last.bits); 1095793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->back += last.bits; 1096793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1097793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(here.bits); 1098793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->back += here.bits; 1099793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (here.op & 64) { 1100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid distance code"; 1101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 1102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->offset = (unsigned)here.val; 1105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->extra = (unsigned)(here.op) & 15; 1106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = DISTEXT; 1107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case DISTEXT: 1108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->extra) { 1109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(state->extra); 1110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->offset += BITS(state->extra); 1111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler DROPBITS(state->extra); 1112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->back += state->extra; 1113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef INFLATE_STRICT 1115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->offset > state->dmax) { 1116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid distance too far back"; 1117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 1118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 1121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracevv((stderr, "inflate: distance %u\n", state->offset)); 1122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = MATCH; 1123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case MATCH: 1124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (left == 0) goto inf_leave; 1125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = out - left; 1126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->offset > copy) { /* copy from window */ 1127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = state->offset - copy; 1128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy > state->whave) { 1129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->sane) { 1130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"invalid distance too far back"; 1131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 1132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 1135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Trace((stderr, "inflate.c too far\n")); 1136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy -= state->whave; 1137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy > state->length) copy = state->length; 1138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy > left) copy = left; 1139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left -= copy; 1140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length -= copy; 1141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 1142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *put++ = 0; 1143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--copy); 1144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->length == 0) state->mode = LEN; 1145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 1147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy > state->wnext) { 1149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy -= state->wnext; 1150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler from = state->window + (state->wsize - copy); 1151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 1153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler from = state->window + (state->wnext - copy); 1154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy > state->length) copy = state->length; 1155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else { /* copy from output */ 1157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler from = put - state->offset; 1158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = state->length; 1159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy > left) copy = left; 1161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left -= copy; 1162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->length -= copy; 1163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler do { 1164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *put++ = *from++; 1165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } while (--copy); 1166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->length == 0) state->mode = LEN; 1167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case LIT: 1169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (left == 0) goto inf_leave; 1170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *put++ = (unsigned char)(state->length); 1171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler left--; 1172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = LEN; 1173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case CHECK: 1175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->wrap) { 1176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(32); 1177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler out -= left; 1178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->total_out += out; 1179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->total += out; 1180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (out) 1181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->adler = state->check = 1182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UPDATE(state->check, put - out, out); 1183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler out = left; 1184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (( 1185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef GUNZIP 1186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->flags ? hold : 1187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 1188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ZSWAP32(hold)) != state->check) { 1189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"incorrect data check"; 1190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 1191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler INITBITS(); 1194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: check matches trailer\n")); 1195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef GUNZIP 1197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = LENGTH; 1198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case LENGTH: 1199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->wrap && state->flags) { 1200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler NEEDBITS(32); 1201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (hold != (state->total & 0xffffffffUL)) { 1202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->msg = (char *)"incorrect length check"; 1203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = BAD; 1204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler break; 1205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler INITBITS(); 1207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: length matches trailer\n")); 1208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 1210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = DONE; 1211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case DONE: 1212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = Z_STREAM_END; 1213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto inf_leave; 1214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case BAD: 1215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = Z_DATA_ERROR; 1216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler goto inf_leave; 1217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case MEM: 1218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_MEM_ERROR; 1219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler case SYNC: 1220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler default: 1221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_STREAM_ERROR; 1222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* 1225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Return from inflate(), updating the total counts and the check value. 1226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler If there was no progress during the inflate() call, return a buffer 1227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler error. Call updatewindow() to create and/or update the window state. 1228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Note: a memory error from inflate() is non-recoverable. 1229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inf_leave: 1231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler RESTORE(); 1232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->wsize || (out != strm->avail_out && state->mode < BAD && 1233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (state->mode < CHECK || flush != Z_FINISH))) 1234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { 1235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = MEM; 1236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_MEM_ERROR; 1237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler in -= strm->avail_in; 1239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler out -= strm->avail_out; 1240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->total_in += in; 1241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->total_out += out; 1242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->total += out; 1243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->wrap && out) 1244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->adler = state->check = 1245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler UPDATE(state->check, strm->next_out - out, out); 1246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->data_type = state->bits + (state->last ? 64 : 0) + 1247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (state->mode == TYPE ? 128 : 0) + 1248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); 1249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) 1250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = Z_BUF_ERROR; 1251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return ret; 1252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateEnd(strm) 1255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 1256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 1258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) 1259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_STREAM_ERROR; 1260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 1261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->window != Z_NULL) ZFREE(strm, state->window); 1262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ZFREE(strm, strm->state); 1263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->state = Z_NULL; 1264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: end\n")); 1265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_OK; 1266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) 1269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 1270793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerBytef *dictionary; 1271793ee12c6df9cad3806238d32528c49a3ff9331dNoah PresleruInt *dictLength; 1272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 1274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* check state */ 1276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 1277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 1278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* copy dictionary */ 1280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->whave && dictionary != Z_NULL) { 1281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler zmemcpy(dictionary, state->window + state->wnext, 1282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->whave - state->wnext); 1283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler zmemcpy(dictionary + state->whave - state->wnext, 1284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->window, state->wnext); 1285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (dictLength != Z_NULL) 1287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *dictLength = state->whave; 1288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_OK; 1289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) 1292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 1293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerconst Bytef *dictionary; 1294793ee12c6df9cad3806238d32528c49a3ff9331dNoah PresleruInt dictLength; 1295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 1297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned long dictid; 1298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler int ret; 1299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* check state */ 1301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 1302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 1303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->wrap != 0 && state->mode != DICT) 1304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_STREAM_ERROR; 1305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* check for correct dictionary identifier */ 1307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->mode == DICT) { 1308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dictid = adler32(0L, Z_NULL, 0); 1309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dictid = adler32(dictid, dictionary, dictLength); 1310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (dictid != state->check) 1311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_DATA_ERROR; 1312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* copy dictionary to window using updatewindow(), which will amend the 1315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler existing dictionary if appropriate */ 1316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ret = updatewindow(strm, dictionary + dictLength, dictLength); 1317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (ret) { 1318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = MEM; 1319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_MEM_ERROR; 1320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->havedict = 1; 1322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Tracev((stderr, "inflate: dictionary set\n")); 1323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_OK; 1324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateGetHeader(strm, head) 1327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 1328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslergz_headerp head; 1329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 1331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* check state */ 1333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 1334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 1335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; 1336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* save header structure */ 1338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->head = head; 1339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler head->done = 0; 1340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_OK; 1341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found 1345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler or when out of input. When called, *have is the number of pattern bytes 1346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler found in order so far, in 0..3. On return *have is updated to the new 1347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state. If on return *have equals four, then the pattern was found and the 1348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return value is how many bytes were read including the last byte of the 1349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler pattern. If *have is less than four, then the pattern has not been found 1350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler yet and the return value is len. In the latter case, syncsearch() can be 1351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler called again with more data and the *have state. *have is initialized to 1352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler zero for the first call. 1353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerlocal unsigned syncsearch(have, buf, len) 1355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerunsigned FAR *have; 1356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerconst unsigned char FAR *buf; 1357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerunsigned len; 1358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned got; 1360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned next; 1361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler got = *have; 1363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next = 0; 1364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (next < len && got < 4) { 1365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) 1366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler got++; 1367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else if (buf[next]) 1368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler got = 0; 1369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler else 1370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler got = 4 - got; 1371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler next++; 1372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *have = got; 1374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return next; 1375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateSync(strm) 1378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 1379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned len; /* number of bytes to look at or looked at */ 1381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned long in, out; /* temporary to save total_in and total_out */ 1382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char buf[4]; /* to restore bit buffer to byte string */ 1383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 1384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* check parameters */ 1386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 1387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 1388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; 1389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* if first time, start search in bit buffer */ 1391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->mode != SYNC) { 1392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = SYNC; 1393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->hold <<= state->bits & 7; 1394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->bits -= state->bits & 7; 1395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler len = 0; 1396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler while (state->bits >= 8) { 1397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler buf[len++] = (unsigned char)(state->hold); 1398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->hold >>= 8; 1399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->bits -= 8; 1400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->have = 0; 1402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler syncsearch(&(state->have), buf, len); 1403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1404793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* search available input */ 1406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler len = syncsearch(&(state->have), strm->next_in, strm->avail_in); 1407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->avail_in -= len; 1408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->next_in += len; 1409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->total_in += len; 1410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* return no joy or set up to restart inflate() on a new block */ 1412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->have != 4) return Z_DATA_ERROR; 1413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler in = strm->total_in; out = strm->total_out; 1414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflateReset(strm); 1415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler strm->total_in = in; strm->total_out = out; 1416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->mode = TYPE; 1417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_OK; 1418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* 1421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Returns true if inflate is currently at the end of a block generated by 1422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP 1423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler implementation to provide an additional safety check. PPP uses 1424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored 1425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler block. When decompressing, PPP checks that at the end of input packet, 1426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler inflate is waiting for these length bytes. 1427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */ 1428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateSyncPoint(strm) 1429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 1430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 1432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 1434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 1435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return state->mode == STORED && state->bits == 0; 1436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateCopy(dest, source) 1439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp dest; 1440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp source; 1441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 1443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *copy; 1444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned char FAR *window; 1445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler unsigned wsize; 1446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* check input */ 1448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || 1449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) 1450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_STREAM_ERROR; 1451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)source->state; 1452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* allocate space */ 1454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy = (struct inflate_state FAR *) 1455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ZALLOC(source, 1, sizeof(struct inflate_state)); 1456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (copy == Z_NULL) return Z_MEM_ERROR; 1457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler window = Z_NULL; 1458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->window != Z_NULL) { 1459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler window = (unsigned char FAR *) 1460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); 1461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (window == Z_NULL) { 1462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler ZFREE(source, copy); 1463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_MEM_ERROR; 1464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler /* copy state */ 1468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); 1469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); 1470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (state->lencode >= state->codes && 1471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->lencode <= state->codes + ENOUGH - 1) { 1472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy->lencode = copy->codes + (state->lencode - state->codes); 1473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy->distcode = copy->codes + (state->distcode - state->codes); 1474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy->next = copy->codes + (state->next - state->codes); 1476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (window != Z_NULL) { 1477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler wsize = 1U << state->wbits; 1478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler zmemcpy(window, state->window, wsize); 1479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler } 1480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler copy->window = window; 1481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler dest->state = (struct internal_state FAR *)copy; 1482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_OK; 1483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint ZEXPORT inflateUndermine(strm, subvert) 1486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 1487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint subvert; 1488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 1490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; 1492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 1493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->sane = !subvert; 1494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR 1495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_OK; 1496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#else 1497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state->sane = 1; 1498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return Z_DATA_ERROR; 1499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif 1500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerlong ZEXPORT inflateMark(strm) 1503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerz_streamp strm; 1504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{ 1505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler struct inflate_state FAR *state; 1506793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler 1507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; 1508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler state = (struct inflate_state FAR *)strm->state; 1509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler return ((long)(state->back) << 16) + 1510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (state->mode == COPY ? state->length : 1511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler (state->mode == MATCH ? state->was - state->length : 0)); 1512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler} 1513