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