aboutsummaryrefslogtreecommitdiff
path: root/src/zlib/inflate.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/zlib/inflate.c')
-rw-r--r--src/zlib/inflate.c253
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);
-}