Fossil SCM

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

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button