/* inflate.c -- zlib decompression
- * Copyright (C) 1995-2012 Mark Adler
+ * Copyright (C) 1995-2016 Mark Adler
* For conditions of distribution and use, see copyright notice in zlib.h
*/
#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, unsigned out));
+local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
+ unsigned copy));
#ifdef BUILDFIXED
void makefixed OF((void));
#endif
-local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
+local unsigned syncsearch OF((unsigned FAR *have, const 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)
z_streamp strm;
{
struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
strm->total_in = strm->total_out = state->total = 0;
strm->msg = Z_NULL;
{
struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
state->wsize = 0;
state->whave = 0;
struct inflate_state FAR *state;
/* get the state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
/* extract wrap request from windowBits parameter */
windowBits = -windowBits;
}
else {
- wrap = (windowBits >> 4) + 1;
+ wrap = (windowBits >> 4) + 5;
#ifdef GUNZIP
if (windowBits < 48)
windowBits &= 15;
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);
{
struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) 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;
+ if (bits > 16 || state->bits + (uInt)bits > 32) return Z_STREAM_ERROR;
value &= (1L << bits) - 1;
- state->hold += value << state->bits;
- state->bits += bits;
+ state->hold += (unsigned)value << state->bits;
+ state->bits += (uInt)bits;
return Z_OK;
}
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, out)
+local int updatewindow(strm, end, copy)
z_streamp strm;
-unsigned out;
+const Bytef *end;
+unsigned copy;
{
struct inflate_state FAR *state;
- unsigned copy, dist;
+ unsigned dist;
state = (struct inflate_state FAR *)strm->state;
}
/* copy state->wsize or less output bytes into the circular window */
- copy = out - strm->avail_out;
if (copy >= state->wsize) {
- zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
+ zmemcpy(state->window, end - 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, strm->next_out - copy, dist);
+ zmemcpy(state->window + state->wnext, end - copy, dist);
copy -= dist;
if (copy) {
- zmemcpy(state->window, strm->next_out - copy, copy);
+ zmemcpy(state->window, end - copy, copy);
state->wnext = copy;
state->whave = state->wsize;
}
int flush;
{
struct inflate_state FAR *state;
- unsigned char FAR *next; /* next input */
+ z_const unsigned char FAR *next; /* next input */
unsigned char FAR *put; /* next output */
unsigned have, left; /* available input and output */
unsigned long hold; /* bit buffer */
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 (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+ if (inflateStateCheck(strm) || strm->next_out == Z_NULL ||
(strm->next_in == Z_NULL && strm->avail_in != 0))
return Z_STREAM_ERROR;
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();
len = BITS(4) + 8;
if (state->wbits == 0)
state->wbits = len;
- else if (len > state->wbits) {
+ if (len > 15 || len > state->wbits) {
strm->msg = (char *)"invalid window size";
state->mode = BAD;
break;
}
if (state->head != Z_NULL)
state->head->text = (int)((hold >> 8) & 1);
- if (state->flags & 0x0200) CRC2(state->check, hold);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ 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) CRC4(state->check, hold);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC4(state->check, hold);
INITBITS();
state->mode = OS;
case OS:
state->head->xflags = (int)(hold & 0xff);
state->head->os = (int)(hold >> 8);
}
- if (state->flags & 0x0200) CRC2(state->check, hold);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC2(state->check, hold);
INITBITS();
state->mode = EXLEN;
case EXLEN:
state->length = (unsigned)(hold);
if (state->head != Z_NULL)
state->head->extra_len = (unsigned)hold;
- if (state->flags & 0x0200) CRC2(state->check, hold);
+ if ((state->flags & 0x0200) && (state->wrap & 4))
+ CRC2(state->check, hold);
INITBITS();
}
else if (state->head != Z_NULL)
len + copy > state->head->extra_max ?
state->head->extra_max - len : copy);
}
- if (state->flags & 0x0200)
+ if ((state->flags & 0x0200) && (state->wrap & 4))
state->check = crc32(state->check, next, copy);
have -= copy;
next += copy;
if (state->head != Z_NULL &&
state->head->name != Z_NULL &&
state->length < state->head->name_max)
- state->head->name[state->length++] = len;
+ state->head->name[state->length++] = (Bytef)len;
} while (len && copy < have);
- if (state->flags & 0x0200)
+ if ((state->flags & 0x0200) && (state->wrap & 4))
state->check = crc32(state->check, next, copy);
have -= copy;
next += copy;
if (state->head != Z_NULL &&
state->head->comment != Z_NULL &&
state->length < state->head->comm_max)
- state->head->comment[state->length++] = len;
+ state->head->comment[state->length++] = (Bytef)len;
} while (len && copy < have);
- if (state->flags & 0x0200)
+ if ((state->flags & 0x0200) && (state->wrap & 4))
state->check = crc32(state->check, next, copy);
have -= copy;
next += copy;
case HCRC:
if (state->flags & 0x0200) {
NEEDBITS(16);
- if (hold != (state->check & 0xffff)) {
+ if ((state->wrap & 4) && hold != (state->check & 0xffff)) {
strm->msg = (char *)"header crc mismatch";
state->mode = BAD;
break;
while (state->have < 19)
state->lens[order[state->have++]] = 0;
state->next = state->codes;
- state->lencode = (code const FAR *)(state->next);
+ state->lencode = (const code FAR *)(state->next);
state->lenbits = 7;
ret = inflate_table(CODES, state->lens, 19, &(state->next),
&(state->lenbits), state->work);
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 = (code const FAR *)(state->next);
+ state->lencode = (const code FAR *)(state->next);
state->lenbits = 9;
ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
&(state->lenbits), state->work);
state->mode = BAD;
break;
}
- state->distcode = (code const FAR *)(state->next);
+ state->distcode = (const code FAR *)(state->next);
state->distbits = 6;
ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
&(state->next), &(state->distbits), state->work);
out -= left;
strm->total_out += out;
state->total += out;
- if (out)
+ if ((state->wrap & 4) && out)
strm->adler = state->check =
UPDATE(state->check, put - out, out);
out = left;
- if ((
+ if ((state->wrap & 4) && (
#ifdef GUNZIP
state->flags ? hold :
#endif
RESTORE();
if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
(state->mode < CHECK || flush != Z_FINISH)))
- if (updatewindow(strm, out)) {
+ if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
state->mode = MEM;
return Z_MEM_ERROR;
}
strm->total_in += in;
strm->total_out += out;
state->total += out;
- if (state->wrap && out)
+ if ((state->wrap & 4) && out)
strm->adler = state->check =
UPDATE(state->check, strm->next_out - out, out);
- strm->data_type = state->bits + (state->last ? 64 : 0) +
+ strm->data_type = (int)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)
z_streamp strm;
{
struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+ if (inflateStateCheck(strm))
return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if (state->window != Z_NULL) ZFREE(strm, state->window);
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;
{
struct inflate_state FAR *state;
unsigned long dictid;
- unsigned char *next;
- unsigned avail;
int ret;
/* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if (state->wrap != 0 && state->mode != DICT)
return Z_STREAM_ERROR;
/* copy dictionary to window using updatewindow(), which will amend the
existing dictionary if appropriate */
- next = strm->next_out;
- avail = strm->avail_out;
- strm->next_out = (Bytef *)dictionary + dictLength;
- strm->avail_out = 0;
- ret = updatewindow(strm, dictLength);
- strm->avail_out = avail;
- strm->next_out = next;
+ ret = updatewindow(strm, dictionary + dictLength, dictLength);
if (ret) {
state->mode = MEM;
return Z_MEM_ERROR;
struct inflate_state FAR *state;
/* check state */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
*/
local unsigned syncsearch(have, buf, len)
unsigned FAR *have;
-unsigned char FAR *buf;
+const unsigned char FAR *buf;
unsigned len;
{
unsigned got;
struct inflate_state FAR *state;
/* check parameters */
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
{
struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
return state->mode == STORED && state->bits == 0;
}
unsigned wsize;
/* check input */
- if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
- source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+ if (inflateStateCheck(source) || dest == Z_NULL)
return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)source->state;
/* copy state */
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
+ copy->strm = dest;
if (state->lencode >= state->codes &&
state->lencode <= state->codes + ENOUGH - 1) {
copy->lencode = copy->codes + (state->lencode - state->codes);
{
struct inflate_state FAR *state;
- if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+ if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
- state->sane = !subvert;
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+ state->sane = !subvert;
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 (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
+ if (inflateStateCheck(strm))
+ return -(1L << 16);
state = (struct inflate_state FAR *)strm->state;
- return ((long)(state->back) << 16) +
+ return (long)(((unsigned long)((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);
+}