diff options
author | Ladislav Zezula <ladislav.zezula@avg.com> | 2013-10-11 15:51:18 +0200 |
---|---|---|
committer | Ladislav Zezula <ladislav.zezula@avg.com> | 2013-10-11 15:51:18 +0200 |
commit | 16f2797b8cadde9446d8c9bd694c265f8a058cda (patch) | |
tree | 3859c6a7aa491e35e18c442d3332edf86b0f8b25 /src/zlib/inflate.c | |
parent | 450713b69f2c834cff79434ba5ad8133aac1e400 (diff) |
+ Support for SQP files
+ Several checks added (thanks Dmitry "Vortex" Koteroff)
+ Fixed zlib
+ StormLib no longer changes "/" to "\". Hopefully this won't be problem for Linux and Mac people
Diffstat (limited to 'src/zlib/inflate.c')
-rw-r--r-- | src/zlib/inflate.c | 282 |
1 files changed, 85 insertions, 197 deletions
diff --git a/src/zlib/inflate.c b/src/zlib/inflate.c index a8431ab..792fdee 100644 --- a/src/zlib/inflate.c +++ b/src/zlib/inflate.c @@ -1,5 +1,5 @@ /* inflate.c -- zlib decompression - * Copyright (C) 1995-2010 Mark Adler + * Copyright (C) 1995-2005 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -45,7 +45,7 @@ * - Rearrange window copies in inflate_fast() for speed and simplification * - Unroll last copy for window match in inflate_fast() * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() + * - Pull out common write == 0 case for speed in inflate_fast() * - Make op and len in inflate_fast() unsigned for consistency * - Add FAR to lcode and dcode declarations in inflate_fast() * - Simplified bad distance check in inflate_fast() @@ -117,52 +117,28 @@ z_streamp strm; state->head = Z_NULL; state->wsize = 0; state->whave = 0; - state->wnext = 0; + state->write = 0; state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; Tracev((stderr, "inflate: reset\n")); return Z_OK; } -int ZEXPORT inflateReset2(strm, windowBits) +int ZEXPORT inflatePrime(strm, bits, value) z_streamp strm; -int windowBits; +int bits; +int value; { - int wrap; struct inflate_state FAR *state; - /* get the state */ if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; } int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) @@ -171,7 +147,6 @@ int windowBits; const char *version; int stream_size; { - int ret; struct inflate_state FAR *state; if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || @@ -189,13 +164,24 @@ int stream_size; if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; - state->window = Z_NULL; - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { + if (windowBits < 0) { + state->wrap = 0; + windowBits = -windowBits; + } + else { + state->wrap = (windowBits >> 4) + 1; +#ifdef GUNZIP + if (windowBits < 48) windowBits &= 15; +#endif + } + if (windowBits < 8 || windowBits > 15) { ZFREE(strm, state); strm->state = Z_NULL; + return Z_STREAM_ERROR; } - return ret; + state->wbits = (unsigned)windowBits; + state->window = Z_NULL; + return inflateReset(strm); } int ZEXPORT inflateInit_(strm, version, stream_size) @@ -206,27 +192,6 @@ int stream_size; return inflateInit2_(strm, DEF_WBITS, version, stream_size); } -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; - return Z_OK; -} - /* Return state with length and distance decoding tables and index sizes set to fixed code decoding. Normally this returns fixed tables from inffixed.h. @@ -375,7 +340,7 @@ unsigned out; /* if window not in use yet, initialize */ if (state->wsize == 0) { state->wsize = 1U << state->wbits; - state->wnext = 0; + state->write = 0; state->whave = 0; } @@ -383,22 +348,22 @@ unsigned out; copy = out - strm->avail_out; if (copy >= state->wsize) { zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); - state->wnext = 0; + state->write = 0; state->whave = state->wsize; } else { - dist = state->wsize - state->wnext; + dist = state->wsize - state->write; if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); + zmemcpy(state->window + state->write, strm->next_out - copy, dist); copy -= dist; if (copy) { zmemcpy(state->window, strm->next_out - copy, copy); - state->wnext = copy; + state->write = copy; state->whave = state->wsize; } else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; + state->write += dist; + if (state->write == state->wsize) state->write = 0; if (state->whave < state->wsize) state->whave += dist; } } @@ -599,7 +564,7 @@ int flush; unsigned in, out; /* save starting available input and output */ unsigned copy; /* number of stored or match bytes to copy */ unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ + code this; /* current decoding table entry */ code last; /* parent table entry */ unsigned len; /* length to copy for repeats, bits to drop */ int ret; /* return code */ @@ -654,9 +619,7 @@ int flush; } DROPBITS(4); len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - else if (len > state->wbits) { + if (len > state->wbits) { strm->msg = (char *)"invalid window size"; state->mode = BAD; break; @@ -808,7 +771,7 @@ int flush; strm->adler = state->check = adler32(0L, Z_NULL, 0); state->mode = TYPE; case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + if (flush == Z_BLOCK) goto inf_leave; case TYPEDO: if (state->last) { BYTEBITS(); @@ -828,11 +791,7 @@ int flush; fixedtables(state); Tracev((stderr, "inflate: fixed codes block%s\n", state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } + state->mode = LEN; /* decode codes */ break; case 2: /* dynamic block */ Tracev((stderr, "inflate: dynamic codes block%s\n", @@ -857,9 +816,6 @@ int flush; Tracev((stderr, "inflate: stored length %u\n", state->length)); INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - case COPY_: state->mode = COPY; case COPY: copy = state->length; @@ -920,19 +876,19 @@ int flush; case CODELENS: while (state->have < state->nlen + state->ndist) { for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } - if (here.val < 16) { - NEEDBITS(here.bits); - DROPBITS(here.bits); - state->lens[state->have++] = here.val; + if (this.val < 16) { + NEEDBITS(this.bits); + DROPBITS(this.bits); + state->lens[state->have++] = this.val; } else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); + if (this.val == 16) { + NEEDBITS(this.bits + 2); + DROPBITS(this.bits); if (state->have == 0) { strm->msg = (char *)"invalid bit length repeat"; state->mode = BAD; @@ -942,16 +898,16 @@ int flush; copy = 3 + BITS(2); DROPBITS(2); } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); + else if (this.val == 17) { + NEEDBITS(this.bits + 3); + DROPBITS(this.bits); len = 0; copy = 3 + BITS(3); DROPBITS(3); } else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); + NEEDBITS(this.bits + 7); + DROPBITS(this.bits); len = 0; copy = 11 + BITS(7); DROPBITS(7); @@ -969,16 +925,7 @@ int flush; /* handle error breaks in while */ if (state->mode == BAD) break; - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ + /* build code tables */ state->next = state->codes; state->lencode = (code const FAR *)(state->next); state->lenbits = 9; @@ -999,102 +946,88 @@ int flush; break; } Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - case LEN_: state->mode = LEN; case LEN: if (have >= 6 && left >= 258) { RESTORE(); inflate_fast(strm, out); LOAD(); - if (state->mode == TYPE) - state->back = -1; break; } - state->back = 0; for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; + this = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } - if (here.op && (here.op & 0xf0) == 0) { - last = here; + if (this.op && (this.op & 0xf0) == 0) { + last = this; for (;;) { - here = state->lencode[last.val + + this = state->lencode[last.val + (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; + if ((unsigned)(last.bits + this.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); - state->back += last.bits; } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? + DROPBITS(this.bits); + state->length = (unsigned)this.val; + if ((int)(this.op) == 0) { + Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ? "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); + "inflate: literal 0x%02x\n", this.val)); state->mode = LIT; break; } - if (here.op & 32) { + if (this.op & 32) { Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; state->mode = TYPE; break; } - if (here.op & 64) { + if (this.op & 64) { strm->msg = (char *)"invalid literal/length code"; state->mode = BAD; break; } - state->extra = (unsigned)(here.op) & 15; + state->extra = (unsigned)(this.op) & 15; state->mode = LENEXT; case LENEXT: if (state->extra) { NEEDBITS(state->extra); state->length += BITS(state->extra); DROPBITS(state->extra); - state->back += state->extra; } Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; state->mode = DIST; case DIST: for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; + this = state->distcode[BITS(state->distbits)]; + if ((unsigned)(this.bits) <= bits) break; PULLBYTE(); } - if ((here.op & 0xf0) == 0) { - last = here; + if ((this.op & 0xf0) == 0) { + last = this; for (;;) { - here = state->distcode[last.val + + this = state->distcode[last.val + (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; + if ((unsigned)(last.bits + this.bits) <= bits) break; PULLBYTE(); } DROPBITS(last.bits); - state->back += last.bits; } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { + DROPBITS(this.bits); + if (this.op & 64) { strm->msg = (char *)"invalid distance code"; state->mode = BAD; break; } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; + state->offset = (unsigned)this.val; + state->extra = (unsigned)(this.op) & 15; state->mode = DISTEXT; case DISTEXT: if (state->extra) { NEEDBITS(state->extra); state->offset += BITS(state->extra); DROPBITS(state->extra); - state->back += state->extra; } #ifdef INFLATE_STRICT if (state->offset > state->dmax) { @@ -1103,6 +1036,11 @@ int flush; break; } #endif + if (state->offset > state->whave + out - left) { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } Tracevv((stderr, "inflate: distance %u\n", state->offset)); state->mode = MATCH; case MATCH: @@ -1110,32 +1048,12 @@ int flush; copy = out - left; if (state->offset > copy) { /* copy from window */ copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; + if (copy > state->write) { + copy -= state->write; from = state->window + (state->wsize - copy); } else - from = state->window + (state->wnext - copy); + from = state->window + (state->write - copy); if (copy > state->length) copy = state->length; } else { /* copy from output */ @@ -1228,8 +1146,7 @@ int flush; strm->adler = state->check = UPDATE(state->check, strm->next_out - out, out); strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + (state->mode == TYPE ? 128 : 0); if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) ret = Z_BUF_ERROR; return ret; @@ -1449,32 +1366,3 @@ z_streamp source; dest->state = (struct internal_state FAR *)copy; return Z_OK; } - -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->sane = !subvert; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - return Z_OK; -#else - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; - state = (struct inflate_state FAR *)strm->state; - return ((long)(state->back) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} |