1ab9e68a2SToomas Soome /* infback.c -- inflate using a call-back interface 2*64c3d159SToomas Soome * Copyright (C) 1995-2022 Mark Adler 3ab9e68a2SToomas Soome * For conditions of distribution and use, see copyright notice in zlib.h 4ab9e68a2SToomas Soome */ 5ab9e68a2SToomas Soome 6ab9e68a2SToomas Soome /* 7ab9e68a2SToomas Soome This code is largely copied from inflate.c. Normally either infback.o or 8ab9e68a2SToomas Soome inflate.o would be linked into an application--not both. The interface 9ab9e68a2SToomas Soome with inffast.c is retained so that optimized assembler-coded versions of 10ab9e68a2SToomas Soome inflate_fast() can be used with either inflate.c or infback.c. 11ab9e68a2SToomas Soome */ 12ab9e68a2SToomas Soome 13ab9e68a2SToomas Soome #include "zutil.h" 14ab9e68a2SToomas Soome #include "inftrees.h" 15ab9e68a2SToomas Soome #include "inflate.h" 16ab9e68a2SToomas Soome #include "inffast.h" 17ab9e68a2SToomas Soome 18ab9e68a2SToomas Soome /* function prototypes */ 19ab9e68a2SToomas Soome local void fixedtables OF((struct inflate_state FAR *state)); 20ab9e68a2SToomas Soome 21ab9e68a2SToomas Soome /* 22ab9e68a2SToomas Soome strm provides memory allocation functions in zalloc and zfree, or 23ab9e68a2SToomas Soome Z_NULL to use the library memory allocation functions. 24ab9e68a2SToomas Soome 25ab9e68a2SToomas Soome windowBits is in the range 8..15, and window is a user-supplied 26ab9e68a2SToomas Soome window and output buffer that is 2**windowBits bytes. 27ab9e68a2SToomas Soome */ 28ab9e68a2SToomas Soome int ZEXPORT inflateBackInit_(z_streamp strm, int windowBits, 29ab9e68a2SToomas Soome unsigned char FAR *window, const char *version, int stream_size) 30ab9e68a2SToomas Soome { 31ab9e68a2SToomas Soome struct inflate_state FAR *state; 32ab9e68a2SToomas Soome 33ab9e68a2SToomas Soome if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || 34ab9e68a2SToomas Soome stream_size != (int)(sizeof(z_stream))) 35ab9e68a2SToomas Soome return Z_VERSION_ERROR; 36ab9e68a2SToomas Soome if (strm == Z_NULL || window == Z_NULL || 37ab9e68a2SToomas Soome windowBits < 8 || windowBits > 15) 38ab9e68a2SToomas Soome return Z_STREAM_ERROR; 39ab9e68a2SToomas Soome strm->msg = Z_NULL; /* in case we return an error */ 40ab9e68a2SToomas Soome if (strm->zalloc == (alloc_func)0) { 41ab9e68a2SToomas Soome #ifdef Z_SOLO 42ab9e68a2SToomas Soome return Z_STREAM_ERROR; 43ab9e68a2SToomas Soome #else 44ab9e68a2SToomas Soome strm->zalloc = zcalloc; 45ab9e68a2SToomas Soome strm->opaque = (voidpf)0; 46ab9e68a2SToomas Soome #endif 47ab9e68a2SToomas Soome } 48ab9e68a2SToomas Soome if (strm->zfree == (free_func)0) 49ab9e68a2SToomas Soome #ifdef Z_SOLO 50ab9e68a2SToomas Soome return Z_STREAM_ERROR; 51ab9e68a2SToomas Soome #else 52ab9e68a2SToomas Soome strm->zfree = zcfree; 53ab9e68a2SToomas Soome #endif 54ab9e68a2SToomas Soome state = (struct inflate_state FAR *)ZALLOC(strm, 1, 55ab9e68a2SToomas Soome sizeof(struct inflate_state)); 56ab9e68a2SToomas Soome if (state == Z_NULL) return Z_MEM_ERROR; 57ab9e68a2SToomas Soome Tracev((stderr, "inflate: allocated\n")); 58ab9e68a2SToomas Soome strm->state = (struct internal_state FAR *)state; 59ab9e68a2SToomas Soome state->dmax = 32768U; 60ab9e68a2SToomas Soome state->wbits = (uInt)windowBits; 61ab9e68a2SToomas Soome state->wsize = 1U << windowBits; 62ab9e68a2SToomas Soome state->window = window; 63ab9e68a2SToomas Soome state->wnext = 0; 64ab9e68a2SToomas Soome state->whave = 0; 65ab9e68a2SToomas Soome return Z_OK; 66ab9e68a2SToomas Soome } 67ab9e68a2SToomas Soome 68ab9e68a2SToomas Soome /* 69ab9e68a2SToomas Soome Return state with length and distance decoding tables and index sizes set to 70ab9e68a2SToomas Soome fixed code decoding. Normally this returns fixed tables from inffixed.h. 71ab9e68a2SToomas Soome If BUILDFIXED is defined, then instead this routine builds the tables the 72ab9e68a2SToomas Soome first time it's called, and returns those tables the first time and 73ab9e68a2SToomas Soome thereafter. This reduces the size of the code by about 2K bytes, in 74ab9e68a2SToomas Soome exchange for a little execution time. However, BUILDFIXED should not be 75ab9e68a2SToomas Soome used for threaded applications, since the rewriting of the tables and virgin 76ab9e68a2SToomas Soome may not be thread-safe. 77ab9e68a2SToomas Soome */ 78ab9e68a2SToomas Soome local void fixedtables(struct inflate_state FAR *state) 79ab9e68a2SToomas Soome { 80ab9e68a2SToomas Soome #ifdef BUILDFIXED 81ab9e68a2SToomas Soome static int virgin = 1; 82ab9e68a2SToomas Soome static code *lenfix, *distfix; 83ab9e68a2SToomas Soome static code fixed[544]; 84ab9e68a2SToomas Soome 85ab9e68a2SToomas Soome /* build fixed huffman tables if first call (may not be thread safe) */ 86ab9e68a2SToomas Soome if (virgin) { 87ab9e68a2SToomas Soome unsigned sym, bits; 88ab9e68a2SToomas Soome static code *next; 89ab9e68a2SToomas Soome 90ab9e68a2SToomas Soome /* literal/length table */ 91ab9e68a2SToomas Soome sym = 0; 92ab9e68a2SToomas Soome while (sym < 144) state->lens[sym++] = 8; 93ab9e68a2SToomas Soome while (sym < 256) state->lens[sym++] = 9; 94ab9e68a2SToomas Soome while (sym < 280) state->lens[sym++] = 7; 95ab9e68a2SToomas Soome while (sym < 288) state->lens[sym++] = 8; 96ab9e68a2SToomas Soome next = fixed; 97ab9e68a2SToomas Soome lenfix = next; 98ab9e68a2SToomas Soome bits = 9; 99ab9e68a2SToomas Soome inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); 100ab9e68a2SToomas Soome 101ab9e68a2SToomas Soome /* distance table */ 102ab9e68a2SToomas Soome sym = 0; 103ab9e68a2SToomas Soome while (sym < 32) state->lens[sym++] = 5; 104ab9e68a2SToomas Soome distfix = next; 105ab9e68a2SToomas Soome bits = 5; 106ab9e68a2SToomas Soome inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); 107ab9e68a2SToomas Soome 108ab9e68a2SToomas Soome /* do this just once */ 109ab9e68a2SToomas Soome virgin = 0; 110ab9e68a2SToomas Soome } 111ab9e68a2SToomas Soome #else /* !BUILDFIXED */ 112ab9e68a2SToomas Soome # include "inffixed.h" 113ab9e68a2SToomas Soome #endif /* BUILDFIXED */ 114ab9e68a2SToomas Soome state->lencode = lenfix; 115ab9e68a2SToomas Soome state->lenbits = 9; 116ab9e68a2SToomas Soome state->distcode = distfix; 117ab9e68a2SToomas Soome state->distbits = 5; 118ab9e68a2SToomas Soome } 119ab9e68a2SToomas Soome 120ab9e68a2SToomas Soome /* Macros for inflateBack(): */ 121ab9e68a2SToomas Soome 122ab9e68a2SToomas Soome /* Load returned state from inflate_fast() */ 123ab9e68a2SToomas Soome #define LOAD() \ 124ab9e68a2SToomas Soome do { \ 125ab9e68a2SToomas Soome put = strm->next_out; \ 126ab9e68a2SToomas Soome left = strm->avail_out; \ 127ab9e68a2SToomas Soome next = strm->next_in; \ 128ab9e68a2SToomas Soome have = strm->avail_in; \ 129ab9e68a2SToomas Soome hold = state->hold; \ 130ab9e68a2SToomas Soome bits = state->bits; \ 131ab9e68a2SToomas Soome } while (0) 132ab9e68a2SToomas Soome 133ab9e68a2SToomas Soome /* Set state from registers for inflate_fast() */ 134ab9e68a2SToomas Soome #define RESTORE() \ 135ab9e68a2SToomas Soome do { \ 136ab9e68a2SToomas Soome strm->next_out = put; \ 137ab9e68a2SToomas Soome strm->avail_out = left; \ 138ab9e68a2SToomas Soome strm->next_in = next; \ 139ab9e68a2SToomas Soome strm->avail_in = have; \ 140ab9e68a2SToomas Soome state->hold = hold; \ 141ab9e68a2SToomas Soome state->bits = bits; \ 142ab9e68a2SToomas Soome } while (0) 143ab9e68a2SToomas Soome 144ab9e68a2SToomas Soome /* Clear the input bit accumulator */ 145ab9e68a2SToomas Soome #define INITBITS() \ 146ab9e68a2SToomas Soome do { \ 147ab9e68a2SToomas Soome hold = 0; \ 148ab9e68a2SToomas Soome bits = 0; \ 149ab9e68a2SToomas Soome } while (0) 150ab9e68a2SToomas Soome 151ab9e68a2SToomas Soome /* Assure that some input is available. If input is requested, but denied, 152ab9e68a2SToomas Soome then return a Z_BUF_ERROR from inflateBack(). */ 153ab9e68a2SToomas Soome #define PULL() \ 154ab9e68a2SToomas Soome do { \ 155ab9e68a2SToomas Soome if (have == 0) { \ 156ab9e68a2SToomas Soome have = in(in_desc, &next); \ 157ab9e68a2SToomas Soome if (have == 0) { \ 158ab9e68a2SToomas Soome next = Z_NULL; \ 159ab9e68a2SToomas Soome ret = Z_BUF_ERROR; \ 160ab9e68a2SToomas Soome goto inf_leave; \ 161ab9e68a2SToomas Soome } \ 162ab9e68a2SToomas Soome } \ 163ab9e68a2SToomas Soome } while (0) 164ab9e68a2SToomas Soome 165ab9e68a2SToomas Soome /* Get a byte of input into the bit accumulator, or return from inflateBack() 166ab9e68a2SToomas Soome with an error if there is no input available. */ 167ab9e68a2SToomas Soome #define PULLBYTE() \ 168ab9e68a2SToomas Soome do { \ 169ab9e68a2SToomas Soome PULL(); \ 170ab9e68a2SToomas Soome have--; \ 171ab9e68a2SToomas Soome hold += (unsigned long)(*next++) << bits; \ 172ab9e68a2SToomas Soome bits += 8; \ 173ab9e68a2SToomas Soome } while (0) 174ab9e68a2SToomas Soome 175ab9e68a2SToomas Soome /* Assure that there are at least n bits in the bit accumulator. If there is 176ab9e68a2SToomas Soome not enough available input to do that, then return from inflateBack() with 177ab9e68a2SToomas Soome an error. */ 178ab9e68a2SToomas Soome #define NEEDBITS(n) \ 179ab9e68a2SToomas Soome do { \ 180ab9e68a2SToomas Soome while (bits < (unsigned)(n)) \ 181ab9e68a2SToomas Soome PULLBYTE(); \ 182ab9e68a2SToomas Soome } while (0) 183ab9e68a2SToomas Soome 184ab9e68a2SToomas Soome /* Return the low n bits of the bit accumulator (n < 16) */ 185ab9e68a2SToomas Soome #define BITS(n) \ 186ab9e68a2SToomas Soome ((unsigned)hold & ((1U << (n)) - 1)) 187ab9e68a2SToomas Soome 188ab9e68a2SToomas Soome /* Remove n bits from the bit accumulator */ 189ab9e68a2SToomas Soome #define DROPBITS(n) \ 190ab9e68a2SToomas Soome do { \ 191ab9e68a2SToomas Soome hold >>= (n); \ 192ab9e68a2SToomas Soome bits -= (unsigned)(n); \ 193ab9e68a2SToomas Soome } while (0) 194ab9e68a2SToomas Soome 195ab9e68a2SToomas Soome /* Remove zero to seven bits as needed to go to a byte boundary */ 196ab9e68a2SToomas Soome #define BYTEBITS() \ 197ab9e68a2SToomas Soome do { \ 198ab9e68a2SToomas Soome hold >>= bits & 7; \ 199ab9e68a2SToomas Soome bits -= bits & 7; \ 200ab9e68a2SToomas Soome } while (0) 201ab9e68a2SToomas Soome 202ab9e68a2SToomas Soome /* Assure that some output space is available, by writing out the window 203ab9e68a2SToomas Soome if it's full. If the write fails, return from inflateBack() with a 204ab9e68a2SToomas Soome Z_BUF_ERROR. */ 205ab9e68a2SToomas Soome #define ROOM() \ 206ab9e68a2SToomas Soome do { \ 207ab9e68a2SToomas Soome if (left == 0) { \ 208ab9e68a2SToomas Soome put = state->window; \ 209ab9e68a2SToomas Soome left = state->wsize; \ 210ab9e68a2SToomas Soome state->whave = left; \ 211ab9e68a2SToomas Soome if (out(out_desc, put, left)) { \ 212ab9e68a2SToomas Soome ret = Z_BUF_ERROR; \ 213ab9e68a2SToomas Soome goto inf_leave; \ 214ab9e68a2SToomas Soome } \ 215ab9e68a2SToomas Soome } \ 216ab9e68a2SToomas Soome } while (0) 217ab9e68a2SToomas Soome 218ab9e68a2SToomas Soome /* 219ab9e68a2SToomas Soome strm provides the memory allocation functions and window buffer on input, 220ab9e68a2SToomas Soome and provides information on the unused input on return. For Z_DATA_ERROR 221ab9e68a2SToomas Soome returns, strm will also provide an error message. 222ab9e68a2SToomas Soome 223ab9e68a2SToomas Soome in() and out() are the call-back input and output functions. When 224ab9e68a2SToomas Soome inflateBack() needs more input, it calls in(). When inflateBack() has 225ab9e68a2SToomas Soome filled the window with output, or when it completes with data in the 226ab9e68a2SToomas Soome window, it calls out() to write out the data. The application must not 227ab9e68a2SToomas Soome change the provided input until in() is called again or inflateBack() 228ab9e68a2SToomas Soome returns. The application must not change the window/output buffer until 229ab9e68a2SToomas Soome inflateBack() returns. 230ab9e68a2SToomas Soome 231ab9e68a2SToomas Soome in() and out() are called with a descriptor parameter provided in the 232ab9e68a2SToomas Soome inflateBack() call. This parameter can be a structure that provides the 233ab9e68a2SToomas Soome information required to do the read or write, as well as accumulated 234ab9e68a2SToomas Soome information on the input and output such as totals and check values. 235ab9e68a2SToomas Soome 236ab9e68a2SToomas Soome in() should return zero on failure. out() should return non-zero on 237ab9e68a2SToomas Soome failure. If either in() or out() fails, than inflateBack() returns a 238ab9e68a2SToomas Soome Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it 239ab9e68a2SToomas Soome was in() or out() that caused in the error. Otherwise, inflateBack() 240ab9e68a2SToomas Soome returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format 241ab9e68a2SToomas Soome error, or Z_MEM_ERROR if it could not allocate memory for the state. 242ab9e68a2SToomas Soome inflateBack() can also return Z_STREAM_ERROR if the input parameters 243ab9e68a2SToomas Soome are not correct, i.e. strm is Z_NULL or the state was not initialized. 244ab9e68a2SToomas Soome */ 245ab9e68a2SToomas Soome int ZEXPORT inflateBack(z_streamp strm, in_func in, void FAR *in_desc, 246ab9e68a2SToomas Soome out_func out, void FAR *out_desc) 247ab9e68a2SToomas Soome { 248ab9e68a2SToomas Soome struct inflate_state FAR *state; 249ab9e68a2SToomas Soome z_const unsigned char FAR *next; /* next input */ 250ab9e68a2SToomas Soome unsigned char FAR *put; /* next output */ 251ab9e68a2SToomas Soome unsigned have, left; /* available input and output */ 252ab9e68a2SToomas Soome unsigned long hold; /* bit buffer */ 253ab9e68a2SToomas Soome unsigned bits; /* bits in bit buffer */ 254ab9e68a2SToomas Soome unsigned copy; /* number of stored or match bytes to copy */ 255ab9e68a2SToomas Soome unsigned char FAR *from; /* where to copy match bytes from */ 256ab9e68a2SToomas Soome code here; /* current decoding table entry */ 257ab9e68a2SToomas Soome code last; /* parent table entry */ 258ab9e68a2SToomas Soome unsigned len; /* length to copy for repeats, bits to drop */ 259ab9e68a2SToomas Soome int ret; /* return code */ 260ab9e68a2SToomas Soome static const unsigned short order[19] = /* permutation of code lengths */ 261ab9e68a2SToomas Soome {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; 262ab9e68a2SToomas Soome 263ab9e68a2SToomas Soome /* Check that the strm exists and that the state was initialized */ 264ab9e68a2SToomas Soome if (strm == Z_NULL || strm->state == Z_NULL) 265ab9e68a2SToomas Soome return Z_STREAM_ERROR; 266ab9e68a2SToomas Soome state = (struct inflate_state FAR *)strm->state; 267ab9e68a2SToomas Soome 268ab9e68a2SToomas Soome /* Reset the state */ 269ab9e68a2SToomas Soome strm->msg = Z_NULL; 270ab9e68a2SToomas Soome state->mode = TYPE; 271ab9e68a2SToomas Soome state->last = 0; 272ab9e68a2SToomas Soome state->whave = 0; 273ab9e68a2SToomas Soome next = strm->next_in; 274ab9e68a2SToomas Soome have = next != Z_NULL ? strm->avail_in : 0; 275ab9e68a2SToomas Soome hold = 0; 276ab9e68a2SToomas Soome bits = 0; 277ab9e68a2SToomas Soome put = state->window; 278ab9e68a2SToomas Soome left = state->wsize; 279ab9e68a2SToomas Soome 280ab9e68a2SToomas Soome /* Inflate until end of block marked as last */ 281ab9e68a2SToomas Soome for (;;) 282ab9e68a2SToomas Soome switch (state->mode) { 283ab9e68a2SToomas Soome case TYPE: 284ab9e68a2SToomas Soome /* determine and dispatch block type */ 285ab9e68a2SToomas Soome if (state->last) { 286ab9e68a2SToomas Soome BYTEBITS(); 287ab9e68a2SToomas Soome state->mode = DONE; 288ab9e68a2SToomas Soome break; 289ab9e68a2SToomas Soome } 290ab9e68a2SToomas Soome NEEDBITS(3); 291ab9e68a2SToomas Soome state->last = BITS(1); 292ab9e68a2SToomas Soome DROPBITS(1); 293ab9e68a2SToomas Soome switch (BITS(2)) { 294ab9e68a2SToomas Soome case 0: /* stored block */ 295ab9e68a2SToomas Soome Tracev((stderr, "inflate: stored block%s\n", 296ab9e68a2SToomas Soome state->last ? " (last)" : "")); 297ab9e68a2SToomas Soome state->mode = STORED; 298ab9e68a2SToomas Soome break; 299ab9e68a2SToomas Soome case 1: /* fixed block */ 300ab9e68a2SToomas Soome fixedtables(state); 301ab9e68a2SToomas Soome Tracev((stderr, "inflate: fixed codes block%s\n", 302ab9e68a2SToomas Soome state->last ? " (last)" : "")); 303ab9e68a2SToomas Soome state->mode = LEN; /* decode codes */ 304ab9e68a2SToomas Soome break; 305ab9e68a2SToomas Soome case 2: /* dynamic block */ 306ab9e68a2SToomas Soome Tracev((stderr, "inflate: dynamic codes block%s\n", 307ab9e68a2SToomas Soome state->last ? " (last)" : "")); 308ab9e68a2SToomas Soome state->mode = TABLE; 309ab9e68a2SToomas Soome break; 310ab9e68a2SToomas Soome case 3: 311ab9e68a2SToomas Soome strm->msg = (char *)"invalid block type"; 312ab9e68a2SToomas Soome state->mode = BAD; 313ab9e68a2SToomas Soome } 314ab9e68a2SToomas Soome DROPBITS(2); 315ab9e68a2SToomas Soome break; 316ab9e68a2SToomas Soome 317ab9e68a2SToomas Soome case STORED: 318ab9e68a2SToomas Soome /* get and verify stored block length */ 319ab9e68a2SToomas Soome BYTEBITS(); /* go to byte boundary */ 320ab9e68a2SToomas Soome NEEDBITS(32); 321ab9e68a2SToomas Soome if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { 322ab9e68a2SToomas Soome strm->msg = (char *)"invalid stored block lengths"; 323ab9e68a2SToomas Soome state->mode = BAD; 324ab9e68a2SToomas Soome break; 325ab9e68a2SToomas Soome } 326ab9e68a2SToomas Soome state->length = (unsigned)hold & 0xffff; 327ab9e68a2SToomas Soome Tracev((stderr, "inflate: stored length %u\n", 328ab9e68a2SToomas Soome state->length)); 329ab9e68a2SToomas Soome INITBITS(); 330ab9e68a2SToomas Soome 331ab9e68a2SToomas Soome /* copy stored block from input to output */ 332ab9e68a2SToomas Soome while (state->length != 0) { 333ab9e68a2SToomas Soome copy = state->length; 334ab9e68a2SToomas Soome PULL(); 335ab9e68a2SToomas Soome ROOM(); 336ab9e68a2SToomas Soome if (copy > have) copy = have; 337ab9e68a2SToomas Soome if (copy > left) copy = left; 338ab9e68a2SToomas Soome zmemcpy(put, next, copy); 339ab9e68a2SToomas Soome have -= copy; 340ab9e68a2SToomas Soome next += copy; 341ab9e68a2SToomas Soome left -= copy; 342ab9e68a2SToomas Soome put += copy; 343ab9e68a2SToomas Soome state->length -= copy; 344ab9e68a2SToomas Soome } 345ab9e68a2SToomas Soome Tracev((stderr, "inflate: stored end\n")); 346ab9e68a2SToomas Soome state->mode = TYPE; 347ab9e68a2SToomas Soome break; 348ab9e68a2SToomas Soome 349ab9e68a2SToomas Soome case TABLE: 350ab9e68a2SToomas Soome /* get dynamic table entries descriptor */ 351ab9e68a2SToomas Soome NEEDBITS(14); 352ab9e68a2SToomas Soome state->nlen = BITS(5) + 257; 353ab9e68a2SToomas Soome DROPBITS(5); 354ab9e68a2SToomas Soome state->ndist = BITS(5) + 1; 355ab9e68a2SToomas Soome DROPBITS(5); 356ab9e68a2SToomas Soome state->ncode = BITS(4) + 4; 357ab9e68a2SToomas Soome DROPBITS(4); 358ab9e68a2SToomas Soome #ifndef PKZIP_BUG_WORKAROUND 359ab9e68a2SToomas Soome if (state->nlen > 286 || state->ndist > 30) { 360ab9e68a2SToomas Soome strm->msg = (char *)"too many length or distance symbols"; 361ab9e68a2SToomas Soome state->mode = BAD; 362ab9e68a2SToomas Soome break; 363ab9e68a2SToomas Soome } 364ab9e68a2SToomas Soome #endif 365ab9e68a2SToomas Soome Tracev((stderr, "inflate: table sizes ok\n")); 366ab9e68a2SToomas Soome 367ab9e68a2SToomas Soome /* get code length code lengths (not a typo) */ 368ab9e68a2SToomas Soome state->have = 0; 369ab9e68a2SToomas Soome while (state->have < state->ncode) { 370ab9e68a2SToomas Soome NEEDBITS(3); 371ab9e68a2SToomas Soome state->lens[order[state->have++]] = (unsigned short)BITS(3); 372ab9e68a2SToomas Soome DROPBITS(3); 373ab9e68a2SToomas Soome } 374ab9e68a2SToomas Soome while (state->have < 19) 375ab9e68a2SToomas Soome state->lens[order[state->have++]] = 0; 376ab9e68a2SToomas Soome state->next = state->codes; 377ab9e68a2SToomas Soome state->lencode = (code const FAR *)(state->next); 378ab9e68a2SToomas Soome state->lenbits = 7; 379ab9e68a2SToomas Soome ret = inflate_table(CODES, state->lens, 19, &(state->next), 380ab9e68a2SToomas Soome &(state->lenbits), state->work); 381ab9e68a2SToomas Soome if (ret) { 382ab9e68a2SToomas Soome strm->msg = (char *)"invalid code lengths set"; 383ab9e68a2SToomas Soome state->mode = BAD; 384ab9e68a2SToomas Soome break; 385ab9e68a2SToomas Soome } 386ab9e68a2SToomas Soome Tracev((stderr, "inflate: code lengths ok\n")); 387ab9e68a2SToomas Soome 388ab9e68a2SToomas Soome /* get length and distance code code lengths */ 389ab9e68a2SToomas Soome state->have = 0; 390ab9e68a2SToomas Soome while (state->have < state->nlen + state->ndist) { 391ab9e68a2SToomas Soome for (;;) { 392ab9e68a2SToomas Soome here = state->lencode[BITS(state->lenbits)]; 393ab9e68a2SToomas Soome if ((unsigned)(here.bits) <= bits) break; 394ab9e68a2SToomas Soome PULLBYTE(); 395ab9e68a2SToomas Soome } 396ab9e68a2SToomas Soome if (here.val < 16) { 397ab9e68a2SToomas Soome DROPBITS(here.bits); 398ab9e68a2SToomas Soome state->lens[state->have++] = here.val; 399ab9e68a2SToomas Soome } 400ab9e68a2SToomas Soome else { 401ab9e68a2SToomas Soome if (here.val == 16) { 402ab9e68a2SToomas Soome NEEDBITS(here.bits + 2); 403ab9e68a2SToomas Soome DROPBITS(here.bits); 404ab9e68a2SToomas Soome if (state->have == 0) { 405ab9e68a2SToomas Soome strm->msg = (char *)"invalid bit length repeat"; 406ab9e68a2SToomas Soome state->mode = BAD; 407ab9e68a2SToomas Soome break; 408ab9e68a2SToomas Soome } 409ab9e68a2SToomas Soome len = (unsigned)(state->lens[state->have - 1]); 410ab9e68a2SToomas Soome copy = 3 + BITS(2); 411ab9e68a2SToomas Soome DROPBITS(2); 412ab9e68a2SToomas Soome } 413ab9e68a2SToomas Soome else if (here.val == 17) { 414ab9e68a2SToomas Soome NEEDBITS(here.bits + 3); 415ab9e68a2SToomas Soome DROPBITS(here.bits); 416ab9e68a2SToomas Soome len = 0; 417ab9e68a2SToomas Soome copy = 3 + BITS(3); 418ab9e68a2SToomas Soome DROPBITS(3); 419ab9e68a2SToomas Soome } 420ab9e68a2SToomas Soome else { 421ab9e68a2SToomas Soome NEEDBITS(here.bits + 7); 422ab9e68a2SToomas Soome DROPBITS(here.bits); 423ab9e68a2SToomas Soome len = 0; 424ab9e68a2SToomas Soome copy = 11 + BITS(7); 425ab9e68a2SToomas Soome DROPBITS(7); 426ab9e68a2SToomas Soome } 427ab9e68a2SToomas Soome if (state->have + copy > state->nlen + state->ndist) { 428ab9e68a2SToomas Soome strm->msg = (char *)"invalid bit length repeat"; 429ab9e68a2SToomas Soome state->mode = BAD; 430ab9e68a2SToomas Soome break; 431ab9e68a2SToomas Soome } 432ab9e68a2SToomas Soome while (copy--) 433ab9e68a2SToomas Soome state->lens[state->have++] = (unsigned short)len; 434ab9e68a2SToomas Soome } 435ab9e68a2SToomas Soome } 436ab9e68a2SToomas Soome 437ab9e68a2SToomas Soome /* handle error breaks in while */ 438ab9e68a2SToomas Soome if (state->mode == BAD) break; 439ab9e68a2SToomas Soome 440ab9e68a2SToomas Soome /* check for end-of-block code (better have one) */ 441ab9e68a2SToomas Soome if (state->lens[256] == 0) { 442ab9e68a2SToomas Soome strm->msg = (char *)"invalid code -- missing end-of-block"; 443ab9e68a2SToomas Soome state->mode = BAD; 444ab9e68a2SToomas Soome break; 445ab9e68a2SToomas Soome } 446ab9e68a2SToomas Soome 447ab9e68a2SToomas Soome /* build code tables -- note: do not change the lenbits or distbits 448ab9e68a2SToomas Soome values here (9 and 6) without reading the comments in inftrees.h 449ab9e68a2SToomas Soome concerning the ENOUGH constants, which depend on those values */ 450ab9e68a2SToomas Soome state->next = state->codes; 451ab9e68a2SToomas Soome state->lencode = (code const FAR *)(state->next); 452ab9e68a2SToomas Soome state->lenbits = 9; 453ab9e68a2SToomas Soome ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), 454ab9e68a2SToomas Soome &(state->lenbits), state->work); 455ab9e68a2SToomas Soome if (ret) { 456ab9e68a2SToomas Soome strm->msg = (char *)"invalid literal/lengths set"; 457ab9e68a2SToomas Soome state->mode = BAD; 458ab9e68a2SToomas Soome break; 459ab9e68a2SToomas Soome } 460ab9e68a2SToomas Soome state->distcode = (code const FAR *)(state->next); 461ab9e68a2SToomas Soome state->distbits = 6; 462ab9e68a2SToomas Soome ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, 463ab9e68a2SToomas Soome &(state->next), &(state->distbits), state->work); 464ab9e68a2SToomas Soome if (ret) { 465ab9e68a2SToomas Soome strm->msg = (char *)"invalid distances set"; 466ab9e68a2SToomas Soome state->mode = BAD; 467ab9e68a2SToomas Soome break; 468ab9e68a2SToomas Soome } 469ab9e68a2SToomas Soome Tracev((stderr, "inflate: codes ok\n")); 470ab9e68a2SToomas Soome state->mode = LEN; 471ab9e68a2SToomas Soome /* FALLTHROUGH */ 472ab9e68a2SToomas Soome case LEN: 473ab9e68a2SToomas Soome /* use inflate_fast() if we have enough input and output */ 474ab9e68a2SToomas Soome if (have >= 6 && left >= 258) { 475ab9e68a2SToomas Soome RESTORE(); 476ab9e68a2SToomas Soome if (state->whave < state->wsize) 477ab9e68a2SToomas Soome state->whave = state->wsize - left; 478ab9e68a2SToomas Soome inflate_fast(strm, state->wsize); 479ab9e68a2SToomas Soome LOAD(); 480ab9e68a2SToomas Soome break; 481ab9e68a2SToomas Soome } 482ab9e68a2SToomas Soome 483ab9e68a2SToomas Soome /* get a literal, length, or end-of-block code */ 484ab9e68a2SToomas Soome for (;;) { 485ab9e68a2SToomas Soome here = state->lencode[BITS(state->lenbits)]; 486ab9e68a2SToomas Soome if ((unsigned)(here.bits) <= bits) break; 487ab9e68a2SToomas Soome PULLBYTE(); 488ab9e68a2SToomas Soome } 489ab9e68a2SToomas Soome if (here.op && (here.op & 0xf0) == 0) { 490ab9e68a2SToomas Soome last = here; 491ab9e68a2SToomas Soome for (;;) { 492ab9e68a2SToomas Soome here = state->lencode[last.val + 493ab9e68a2SToomas Soome (BITS(last.bits + last.op) >> last.bits)]; 494ab9e68a2SToomas Soome if ((unsigned)(last.bits + here.bits) <= bits) break; 495ab9e68a2SToomas Soome PULLBYTE(); 496ab9e68a2SToomas Soome } 497ab9e68a2SToomas Soome DROPBITS(last.bits); 498ab9e68a2SToomas Soome } 499ab9e68a2SToomas Soome DROPBITS(here.bits); 500ab9e68a2SToomas Soome state->length = (unsigned)here.val; 501ab9e68a2SToomas Soome 502ab9e68a2SToomas Soome /* process literal */ 503ab9e68a2SToomas Soome if (here.op == 0) { 504ab9e68a2SToomas Soome Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? 505ab9e68a2SToomas Soome "inflate: literal '%c'\n" : 506ab9e68a2SToomas Soome "inflate: literal 0x%02x\n", here.val)); 507ab9e68a2SToomas Soome ROOM(); 508ab9e68a2SToomas Soome *put++ = (unsigned char)(state->length); 509ab9e68a2SToomas Soome left--; 510ab9e68a2SToomas Soome state->mode = LEN; 511ab9e68a2SToomas Soome break; 512ab9e68a2SToomas Soome } 513ab9e68a2SToomas Soome 514ab9e68a2SToomas Soome /* process end of block */ 515ab9e68a2SToomas Soome if (here.op & 32) { 516ab9e68a2SToomas Soome Tracevv((stderr, "inflate: end of block\n")); 517ab9e68a2SToomas Soome state->mode = TYPE; 518ab9e68a2SToomas Soome break; 519ab9e68a2SToomas Soome } 520ab9e68a2SToomas Soome 521ab9e68a2SToomas Soome /* invalid code */ 522ab9e68a2SToomas Soome if (here.op & 64) { 523ab9e68a2SToomas Soome strm->msg = (char *)"invalid literal/length code"; 524ab9e68a2SToomas Soome state->mode = BAD; 525ab9e68a2SToomas Soome break; 526ab9e68a2SToomas Soome } 527ab9e68a2SToomas Soome 528ab9e68a2SToomas Soome /* length code -- get extra bits, if any */ 529ab9e68a2SToomas Soome state->extra = (unsigned)(here.op) & 15; 530ab9e68a2SToomas Soome if (state->extra != 0) { 531ab9e68a2SToomas Soome NEEDBITS(state->extra); 532ab9e68a2SToomas Soome state->length += BITS(state->extra); 533ab9e68a2SToomas Soome DROPBITS(state->extra); 534ab9e68a2SToomas Soome } 535ab9e68a2SToomas Soome Tracevv((stderr, "inflate: length %u\n", state->length)); 536ab9e68a2SToomas Soome 537ab9e68a2SToomas Soome /* get distance code */ 538ab9e68a2SToomas Soome for (;;) { 539ab9e68a2SToomas Soome here = state->distcode[BITS(state->distbits)]; 540ab9e68a2SToomas Soome if ((unsigned)(here.bits) <= bits) break; 541ab9e68a2SToomas Soome PULLBYTE(); 542ab9e68a2SToomas Soome } 543ab9e68a2SToomas Soome if ((here.op & 0xf0) == 0) { 544ab9e68a2SToomas Soome last = here; 545ab9e68a2SToomas Soome for (;;) { 546ab9e68a2SToomas Soome here = state->distcode[last.val + 547ab9e68a2SToomas Soome (BITS(last.bits + last.op) >> last.bits)]; 548ab9e68a2SToomas Soome if ((unsigned)(last.bits + here.bits) <= bits) break; 549ab9e68a2SToomas Soome PULLBYTE(); 550ab9e68a2SToomas Soome } 551ab9e68a2SToomas Soome DROPBITS(last.bits); 552ab9e68a2SToomas Soome } 553ab9e68a2SToomas Soome DROPBITS(here.bits); 554ab9e68a2SToomas Soome if (here.op & 64) { 555ab9e68a2SToomas Soome strm->msg = (char *)"invalid distance code"; 556ab9e68a2SToomas Soome state->mode = BAD; 557ab9e68a2SToomas Soome break; 558ab9e68a2SToomas Soome } 559ab9e68a2SToomas Soome state->offset = (unsigned)here.val; 560ab9e68a2SToomas Soome 561ab9e68a2SToomas Soome /* get distance extra bits, if any */ 562ab9e68a2SToomas Soome state->extra = (unsigned)(here.op) & 15; 563ab9e68a2SToomas Soome if (state->extra != 0) { 564ab9e68a2SToomas Soome NEEDBITS(state->extra); 565ab9e68a2SToomas Soome state->offset += BITS(state->extra); 566ab9e68a2SToomas Soome DROPBITS(state->extra); 567ab9e68a2SToomas Soome } 568ab9e68a2SToomas Soome if (state->offset > state->wsize - (state->whave < state->wsize ? 569ab9e68a2SToomas Soome left : 0)) { 570ab9e68a2SToomas Soome strm->msg = (char *)"invalid distance too far back"; 571ab9e68a2SToomas Soome state->mode = BAD; 572ab9e68a2SToomas Soome break; 573ab9e68a2SToomas Soome } 574ab9e68a2SToomas Soome Tracevv((stderr, "inflate: distance %u\n", state->offset)); 575ab9e68a2SToomas Soome 576ab9e68a2SToomas Soome /* copy match from window to output */ 577ab9e68a2SToomas Soome do { 578ab9e68a2SToomas Soome ROOM(); 579ab9e68a2SToomas Soome copy = state->wsize - state->offset; 580ab9e68a2SToomas Soome if (copy < left) { 581ab9e68a2SToomas Soome from = put + copy; 582ab9e68a2SToomas Soome copy = left - copy; 583ab9e68a2SToomas Soome } 584ab9e68a2SToomas Soome else { 585ab9e68a2SToomas Soome from = put - state->offset; 586ab9e68a2SToomas Soome copy = left; 587ab9e68a2SToomas Soome } 588ab9e68a2SToomas Soome if (copy > state->length) copy = state->length; 589ab9e68a2SToomas Soome state->length -= copy; 590ab9e68a2SToomas Soome left -= copy; 591ab9e68a2SToomas Soome do { 592ab9e68a2SToomas Soome *put++ = *from++; 593ab9e68a2SToomas Soome } while (--copy); 594ab9e68a2SToomas Soome } while (state->length != 0); 595ab9e68a2SToomas Soome break; 596ab9e68a2SToomas Soome 597ab9e68a2SToomas Soome case DONE: 598ab9e68a2SToomas Soome /* inflate stream terminated properly -- write leftover output */ 599ab9e68a2SToomas Soome ret = Z_STREAM_END; 600ab9e68a2SToomas Soome if (left < state->wsize) { 601ab9e68a2SToomas Soome if (out(out_desc, state->window, state->wsize - left)) 602ab9e68a2SToomas Soome ret = Z_BUF_ERROR; 603ab9e68a2SToomas Soome } 604ab9e68a2SToomas Soome goto inf_leave; 605ab9e68a2SToomas Soome 606ab9e68a2SToomas Soome case BAD: 607ab9e68a2SToomas Soome ret = Z_DATA_ERROR; 608ab9e68a2SToomas Soome goto inf_leave; 609ab9e68a2SToomas Soome 610ab9e68a2SToomas Soome default: /* can't happen, but makes compilers happy */ 611ab9e68a2SToomas Soome ret = Z_STREAM_ERROR; 612ab9e68a2SToomas Soome goto inf_leave; 613ab9e68a2SToomas Soome } 614ab9e68a2SToomas Soome 615ab9e68a2SToomas Soome /* Return unused input */ 616ab9e68a2SToomas Soome inf_leave: 617ab9e68a2SToomas Soome strm->next_in = next; 618ab9e68a2SToomas Soome strm->avail_in = have; 619ab9e68a2SToomas Soome return ret; 620ab9e68a2SToomas Soome } 621ab9e68a2SToomas Soome 622ab9e68a2SToomas Soome int ZEXPORT inflateBackEnd(z_streamp strm) 623ab9e68a2SToomas Soome { 624ab9e68a2SToomas Soome if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) 625ab9e68a2SToomas Soome return Z_STREAM_ERROR; 626ab9e68a2SToomas Soome ZFREE(strm, strm->state); 627ab9e68a2SToomas Soome strm->state = Z_NULL; 628ab9e68a2SToomas Soome Tracev((stderr, "inflate: end\n")); 629ab9e68a2SToomas Soome return Z_OK; 630ab9e68a2SToomas Soome } 631