diff options
Diffstat (limited to 'src/zlib/inflate.c')
-rw-r--r-- | src/zlib/inflate.c | 253 |
1 files changed, 86 insertions, 167 deletions
diff --git a/src/zlib/inflate.c b/src/zlib/inflate.c index ac333e8..a8431ab 100644 --- a/src/zlib/inflate.c +++ b/src/zlib/inflate.c @@ -1,5 +1,5 @@ /* inflate.c -- zlib decompression - * Copyright (C) 1995-2016 Mark Adler + * Copyright (C) 1995-2010 Mark Adler * For conditions of distribution and use, see copyright notice in zlib.h */ @@ -92,46 +92,32 @@ #endif /* function prototypes */ -local int inflateStateCheck OF((z_streamp strm)); local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, - unsigned copy)); +local int updatewindow OF((z_streamp strm, unsigned out)); #ifdef BUILDFIXED void makefixed OF((void)); #endif -local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, +local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, unsigned len)); -local int inflateStateCheck(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) - return 1; - state = (struct inflate_state FAR *)strm->state; - if (state == Z_NULL || state->strm != strm || - state->mode < HEAD || state->mode > SYNC) - return 1; - return 0; -} - -int ZEXPORT inflateResetKeep(strm) +int ZEXPORT inflateReset(strm) z_streamp strm; { struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; strm->total_in = strm->total_out = state->total = 0; strm->msg = Z_NULL; - if (state->wrap) /* to support ill-conceived Java test suite */ - strm->adler = state->wrap & 1; + strm->adler = 1; /* to support ill-conceived Java test suite */ state->mode = HEAD; state->last = 0; state->havedict = 0; state->dmax = 32768U; state->head = Z_NULL; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; state->hold = 0; state->bits = 0; state->lencode = state->distcode = state->next = state->codes; @@ -141,19 +127,6 @@ z_streamp strm; return Z_OK; } -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - return inflateResetKeep(strm); -} - int ZEXPORT inflateReset2(strm, windowBits) z_streamp strm; int windowBits; @@ -162,7 +135,7 @@ int windowBits; struct inflate_state FAR *state; /* get the state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + 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 */ @@ -171,7 +144,7 @@ int windowBits; windowBits = -windowBits; } else { - wrap = (windowBits >> 4) + 5; + wrap = (windowBits >> 4) + 1; #ifdef GUNZIP if (windowBits < 48) windowBits &= 15; @@ -207,27 +180,16 @@ int stream_size; if (strm == Z_NULL) return Z_STREAM_ERROR; strm->msg = Z_NULL; /* in case we return an error */ if (strm->zalloc == (alloc_func)0) { -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else strm->zalloc = zcalloc; strm->opaque = (voidpf)0; -#endif } - if (strm->zfree == (free_func)0) -#ifdef Z_SOLO - return Z_STREAM_ERROR; -#else - strm->zfree = zcfree; -#endif + if (strm->zfree == (free_func)0) strm->zfree = zcfree; state = (struct inflate_state FAR *) ZALLOC(strm, 1, sizeof(struct inflate_state)); if (state == Z_NULL) return Z_MEM_ERROR; Tracev((stderr, "inflate: allocated\n")); strm->state = (struct internal_state FAR *)state; - state->strm = strm; state->window = Z_NULL; - state->mode = HEAD; /* to pass state test in inflateReset2() */ ret = inflateReset2(strm, windowBits); if (ret != Z_OK) { ZFREE(strm, state); @@ -251,17 +213,17 @@ int value; { struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + 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 + (uInt)bits > 32) return Z_STREAM_ERROR; + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; value &= (1L << bits) - 1; - state->hold += (unsigned)value << state->bits; - state->bits += (uInt)bits; + state->hold += value << state->bits; + state->bits += bits; return Z_OK; } @@ -359,8 +321,8 @@ void makefixed() low = 0; for (;;) { if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); + printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, + state.lencode[low].val); if (++low == size) break; putchar(','); } @@ -393,13 +355,12 @@ void makefixed() output will fall in the output data, making match copies simpler and faster. The advantage may be dependent on the size of the processor's data caches. */ -local int updatewindow(strm, end, copy) +local int updatewindow(strm, out) z_streamp strm; -const Bytef *end; -unsigned copy; +unsigned out; { struct inflate_state FAR *state; - unsigned dist; + unsigned copy, dist; state = (struct inflate_state FAR *)strm->state; @@ -419,18 +380,19 @@ unsigned copy; } /* copy state->wsize or less output bytes into the circular window */ + copy = out - strm->avail_out; if (copy >= state->wsize) { - zmemcpy(state->window, end - state->wsize, state->wsize); + zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); state->wnext = 0; state->whave = state->wsize; } else { dist = state->wsize - state->wnext; if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, end - copy, dist); + zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); copy -= dist; if (copy) { - zmemcpy(state->window, end - copy, copy); + zmemcpy(state->window, strm->next_out - copy, copy); state->wnext = copy; state->whave = state->wsize; } @@ -537,6 +499,11 @@ unsigned copy; bits -= bits & 7; \ } while (0) +/* Reverse the bytes in a 32-bit value */ +#define REVERSE(q) \ + ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ + (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + /* inflate() uses a state machine to process as much input data and generate as much output data as possible before returning. The state machine is @@ -624,7 +591,7 @@ z_streamp strm; int flush; { struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *next; /* next input */ unsigned char FAR *put; /* next output */ unsigned have, left; /* available input and output */ unsigned long hold; /* bit buffer */ @@ -642,7 +609,7 @@ int flush; static const unsigned short order[19] = /* permutation of code lengths */ {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - if (inflateStateCheck(strm) || strm->next_out == Z_NULL || + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || (strm->next_in == Z_NULL && strm->avail_in != 0)) return Z_STREAM_ERROR; @@ -662,8 +629,6 @@ int flush; NEEDBITS(16); #ifdef GUNZIP if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - if (state->wbits == 0) - state->wbits = 15; state->check = crc32(0L, Z_NULL, 0); CRC2(state->check, hold); INITBITS(); @@ -691,7 +656,7 @@ int flush; len = BITS(4) + 8; if (state->wbits == 0) state->wbits = len; - if (len > 15 || len > state->wbits) { + else if (len > state->wbits) { strm->msg = (char *)"invalid window size"; state->mode = BAD; break; @@ -718,16 +683,14 @@ int flush; } if (state->head != Z_NULL) state->head->text = (int)((hold >> 8) & 1); - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); + if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = TIME; case TIME: NEEDBITS(32); if (state->head != Z_NULL) state->head->time = hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC4(state->check, hold); + if (state->flags & 0x0200) CRC4(state->check, hold); INITBITS(); state->mode = OS; case OS: @@ -736,8 +699,7 @@ int flush; state->head->xflags = (int)(hold & 0xff); state->head->os = (int)(hold >> 8); } - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); + if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); state->mode = EXLEN; case EXLEN: @@ -746,8 +708,7 @@ int flush; state->length = (unsigned)(hold); if (state->head != Z_NULL) state->head->extra_len = (unsigned)hold; - if ((state->flags & 0x0200) && (state->wrap & 4)) - CRC2(state->check, hold); + if (state->flags & 0x0200) CRC2(state->check, hold); INITBITS(); } else if (state->head != Z_NULL) @@ -765,7 +726,7 @@ int flush; len + copy > state->head->extra_max ? state->head->extra_max - len : copy); } - if ((state->flags & 0x0200) && (state->wrap & 4)) + if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; @@ -784,9 +745,9 @@ int flush; if (state->head != Z_NULL && state->head->name != Z_NULL && state->length < state->head->name_max) - state->head->name[state->length++] = (Bytef)len; + state->head->name[state->length++] = len; } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) + if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; @@ -805,9 +766,9 @@ int flush; if (state->head != Z_NULL && state->head->comment != Z_NULL && state->length < state->head->comm_max) - state->head->comment[state->length++] = (Bytef)len; + state->head->comment[state->length++] = len; } while (len && copy < have); - if ((state->flags & 0x0200) && (state->wrap & 4)) + if (state->flags & 0x0200) state->check = crc32(state->check, next, copy); have -= copy; next += copy; @@ -819,7 +780,7 @@ int flush; case HCRC: if (state->flags & 0x0200) { NEEDBITS(16); - if ((state->wrap & 4) && hold != (state->check & 0xffff)) { + if (hold != (state->check & 0xffff)) { strm->msg = (char *)"header crc mismatch"; state->mode = BAD; break; @@ -836,7 +797,7 @@ int flush; #endif case DICTID: NEEDBITS(32); - strm->adler = state->check = ZSWAP32(hold); + strm->adler = state->check = REVERSE(hold); INITBITS(); state->mode = DICT; case DICT: @@ -944,7 +905,7 @@ int flush; while (state->have < 19) state->lens[order[state->have++]] = 0; state->next = state->codes; - state->lencode = (const code FAR *)(state->next); + state->lencode = (code const FAR *)(state->next); state->lenbits = 7; ret = inflate_table(CODES, state->lens, 19, &(state->next), &(state->lenbits), state->work); @@ -964,6 +925,7 @@ int flush; PULLBYTE(); } if (here.val < 16) { + NEEDBITS(here.bits); DROPBITS(here.bits); state->lens[state->have++] = here.val; } @@ -1018,7 +980,7 @@ int flush; values here (9 and 6) without reading the comments in inftrees.h concerning the ENOUGH constants, which depend on those values */ state->next = state->codes; - state->lencode = (const code FAR *)(state->next); + state->lencode = (code const FAR *)(state->next); state->lenbits = 9; ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), &(state->lenbits), state->work); @@ -1027,7 +989,7 @@ int flush; state->mode = BAD; break; } - state->distcode = (const code FAR *)(state->next); + state->distcode = (code const FAR *)(state->next); state->distbits = 6; ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, &(state->next), &(state->distbits), state->work); @@ -1200,15 +1162,15 @@ int flush; out -= left; strm->total_out += out; state->total += out; - if ((state->wrap & 4) && out) + if (out) strm->adler = state->check = UPDATE(state->check, put - out, out); out = left; - if ((state->wrap & 4) && ( + if (( #ifdef GUNZIP state->flags ? hold : #endif - ZSWAP32(hold)) != state->check) { + REVERSE(hold)) != state->check) { strm->msg = (char *)"incorrect data check"; state->mode = BAD; break; @@ -1252,9 +1214,8 @@ int flush; */ inf_leave: RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && - (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { + if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) + if (updatewindow(strm, out)) { state->mode = MEM; return Z_MEM_ERROR; } @@ -1263,10 +1224,10 @@ int flush; strm->total_in += in; strm->total_out += out; state->total += out; - if ((state->wrap & 4) && out) + if (state->wrap && out) strm->adler = state->check = UPDATE(state->check, strm->next_out - out, out); - strm->data_type = (int)state->bits + (state->last ? 64 : 0) + + strm->data_type = state->bits + (state->last ? 64 : 0) + (state->mode == TYPE ? 128 : 0) + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) @@ -1278,7 +1239,7 @@ int ZEXPORT inflateEnd(strm) z_streamp strm; { struct inflate_state FAR *state; - if (inflateStateCheck(strm)) + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->window != Z_NULL) ZFREE(strm, state->window); @@ -1288,59 +1249,43 @@ z_streamp strm; return Z_OK; } -int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) -z_streamp strm; -Bytef *dictionary; -uInt *dictLength; -{ - struct inflate_state FAR *state; - - /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* copy dictionary */ - if (state->whave && dictionary != Z_NULL) { - zmemcpy(dictionary, state->window + state->wnext, - state->whave - state->wnext); - zmemcpy(dictionary + state->whave - state->wnext, - state->window, state->wnext); - } - if (dictLength != Z_NULL) - *dictLength = state->whave; - return Z_OK; -} - int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) z_streamp strm; const Bytef *dictionary; uInt dictLength; { struct inflate_state FAR *state; - unsigned long dictid; - int ret; + unsigned long id; /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (state->wrap != 0 && state->mode != DICT) return Z_STREAM_ERROR; - /* check for correct dictionary identifier */ + /* check for correct dictionary id */ if (state->mode == DICT) { - dictid = adler32(0L, Z_NULL, 0); - dictid = adler32(dictid, dictionary, dictLength); - if (dictid != state->check) + id = adler32(0L, Z_NULL, 0); + id = adler32(id, dictionary, dictLength); + if (id != state->check) return Z_DATA_ERROR; } - /* copy dictionary to window using updatewindow(), which will amend the - existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary + dictLength, dictLength); - if (ret) { + /* copy dictionary to window */ + if (updatewindow(strm, strm->avail_out)) { state->mode = MEM; return Z_MEM_ERROR; } + if (dictLength > state->wsize) { + zmemcpy(state->window, dictionary + dictLength - state->wsize, + state->wsize); + state->whave = state->wsize; + } + else { + zmemcpy(state->window + state->wsize - dictLength, dictionary, + dictLength); + state->whave = dictLength; + } state->havedict = 1; Tracev((stderr, "inflate: dictionary set\n")); return Z_OK; @@ -1353,7 +1298,7 @@ gz_headerp head; struct inflate_state FAR *state; /* check state */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; @@ -1376,7 +1321,7 @@ gz_headerp head; */ local unsigned syncsearch(have, buf, len) unsigned FAR *have; -const unsigned char FAR *buf; +unsigned char FAR *buf; unsigned len; { unsigned got; @@ -1406,7 +1351,7 @@ z_streamp strm; struct inflate_state FAR *state; /* check parameters */ - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; @@ -1453,7 +1398,7 @@ z_streamp strm; { struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; return state->mode == STORED && state->bits == 0; } @@ -1468,7 +1413,8 @@ z_streamp source; unsigned wsize; /* check input */ - if (inflateStateCheck(source) || dest == Z_NULL) + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)source->state; @@ -1487,9 +1433,8 @@ z_streamp source; } /* copy state */ - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); - copy->strm = dest; + zmemcpy(dest, source, sizeof(z_stream)); + zmemcpy(copy, state, sizeof(struct inflate_state)); if (state->lencode >= state->codes && state->lencode <= state->codes + ENOUGH - 1) { copy->lencode = copy->codes + (state->lencode - state->codes); @@ -1511,51 +1456,25 @@ int subvert; { struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; state = (struct inflate_state FAR *)strm->state; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR state->sane = !subvert; +#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR return Z_OK; #else - (void)subvert; state->sane = 1; return Z_DATA_ERROR; #endif } -int ZEXPORT inflateValidate(strm, check) -z_streamp strm; -int check; -{ - struct inflate_state FAR *state; - - if (inflateStateCheck(strm)) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (check) - state->wrap |= 4; - else - state->wrap &= ~4; - return Z_OK; -} - long ZEXPORT inflateMark(strm) z_streamp strm; { struct inflate_state FAR *state; - if (inflateStateCheck(strm)) - return -(1L << 16); + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; state = (struct inflate_state FAR *)strm->state; - return (long)(((unsigned long)((long)state->back)) << 16) + + return ((long)(state->back) << 16) + (state->mode == COPY ? state->length : (state->mode == MATCH ? state->was - state->length : 0)); } - -unsigned long ZEXPORT inflateCodesUsed(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (inflateStateCheck(strm)) return (unsigned long)-1; - state = (struct inflate_state FAR *)strm->state; - return (unsigned long)(state->next - state->codes); -} |