提交 b516b4bd 编写于 作者: M Mark Adler

Do a more thorough check of the state for every stream call.

This verifies that the state has been initialized, that it is the
expected type of state, deflate or inflate, and that at least the
first several bytes of the internal state have not been clobbered.
上级 77fd7e56
...@@ -73,6 +73,7 @@ typedef enum { ...@@ -73,6 +73,7 @@ typedef enum {
typedef block_state (*compress_func) OF((deflate_state *s, int flush)); typedef block_state (*compress_func) OF((deflate_state *s, int flush));
/* Compression function. Returns the block state after the call. */ /* Compression function. Returns the block state after the call. */
local int deflateStateCheck OF((z_streamp strm));
local void fill_window OF((deflate_state *s)); local void fill_window OF((deflate_state *s));
local block_state deflate_stored OF((deflate_state *s, int flush)); local block_state deflate_stored OF((deflate_state *s, int flush));
local block_state deflate_fast OF((deflate_state *s, int flush)); local block_state deflate_fast OF((deflate_state *s, int flush));
...@@ -271,6 +272,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, ...@@ -271,6 +272,7 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
if (s == Z_NULL) return Z_MEM_ERROR; if (s == Z_NULL) return Z_MEM_ERROR;
strm->state = (struct internal_state FAR *)s; strm->state = (struct internal_state FAR *)s;
s->strm = strm; s->strm = strm;
s->status = INIT_STATE; /* to pass state test in deflateReset() */
s->wrap = wrap; s->wrap = wrap;
s->gzhead = Z_NULL; s->gzhead = Z_NULL;
...@@ -312,6 +314,28 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, ...@@ -312,6 +314,28 @@ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
return deflateReset(strm); return deflateReset(strm);
} }
/* =========================================================================
* Check for a valid deflate stream state. Return 0 if ok, 1 if not.
*/
local int deflateStateCheck (strm)
z_streamp strm;
{
deflate_state *s;
if (strm == Z_NULL ||
strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0)
return 1;
s = strm->state;
if (s == Z_NULL || s->strm != strm || (s->status != INIT_STATE &&
s->status != EXTRA_STATE &&
s->status != NAME_STATE &&
s->status != COMMENT_STATE &&
s->status != HCRC_STATE &&
s->status != BUSY_STATE &&
s->status != FINISH_STATE))
return 1;
return 0;
}
/* ========================================================================= */ /* ========================================================================= */
int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
z_streamp strm; z_streamp strm;
...@@ -324,7 +348,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) ...@@ -324,7 +348,7 @@ int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
unsigned avail; unsigned avail;
z_const unsigned char *next; z_const unsigned char *next;
if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) if (deflateStateCheck(strm) || dictionary == Z_NULL)
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
s = strm->state; s = strm->state;
wrap = s->wrap; wrap = s->wrap;
...@@ -387,8 +411,7 @@ int ZEXPORT deflateResetKeep (strm) ...@@ -387,8 +411,7 @@ int ZEXPORT deflateResetKeep (strm)
{ {
deflate_state *s; deflate_state *s;
if (strm == Z_NULL || strm->state == Z_NULL || if (deflateStateCheck(strm)) {
strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
...@@ -433,8 +456,8 @@ int ZEXPORT deflateSetHeader (strm, head) ...@@ -433,8 +456,8 @@ int ZEXPORT deflateSetHeader (strm, head)
z_streamp strm; z_streamp strm;
gz_headerp head; gz_headerp head;
{ {
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (deflateStateCheck(strm) || strm->state->wrap != 2)
if (strm->state->wrap != 2) return Z_STREAM_ERROR; return Z_STREAM_ERROR;
strm->state->gzhead = head; strm->state->gzhead = head;
return Z_OK; return Z_OK;
} }
...@@ -445,7 +468,7 @@ int ZEXPORT deflatePending (strm, pending, bits) ...@@ -445,7 +468,7 @@ int ZEXPORT deflatePending (strm, pending, bits)
int *bits; int *bits;
z_streamp strm; z_streamp strm;
{ {
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
if (pending != Z_NULL) if (pending != Z_NULL)
*pending = strm->state->pending; *pending = strm->state->pending;
if (bits != Z_NULL) if (bits != Z_NULL)
...@@ -462,7 +485,7 @@ int ZEXPORT deflatePrime (strm, bits, value) ...@@ -462,7 +485,7 @@ int ZEXPORT deflatePrime (strm, bits, value)
deflate_state *s; deflate_state *s;
int put; int put;
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
s = strm->state; s = strm->state;
if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
return Z_BUF_ERROR; return Z_BUF_ERROR;
...@@ -489,7 +512,7 @@ int ZEXPORT deflateParams(strm, level, strategy) ...@@ -489,7 +512,7 @@ int ZEXPORT deflateParams(strm, level, strategy)
compress_func func; compress_func func;
int err = Z_OK; int err = Z_OK;
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
s = strm->state; s = strm->state;
#ifdef FASTEST #ifdef FASTEST
...@@ -529,7 +552,7 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) ...@@ -529,7 +552,7 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
{ {
deflate_state *s; deflate_state *s;
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
s = strm->state; s = strm->state;
s->good_match = (uInt)good_length; s->good_match = (uInt)good_length;
s->max_lazy_match = (uInt)max_lazy; s->max_lazy_match = (uInt)max_lazy;
...@@ -568,7 +591,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen) ...@@ -568,7 +591,7 @@ uLong ZEXPORT deflateBound(strm, sourceLen)
((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
/* if can't get parameters, return conservative bound plus zlib wrapper */ /* if can't get parameters, return conservative bound plus zlib wrapper */
if (strm == Z_NULL || strm->state == Z_NULL) if (deflateStateCheck(strm))
return complen + 6; return complen + 6;
/* compute wrapper length */ /* compute wrapper length */
...@@ -661,8 +684,7 @@ int ZEXPORT deflate (strm, flush) ...@@ -661,8 +684,7 @@ int ZEXPORT deflate (strm, flush)
int old_flush; /* value of flush param for previous deflate call */ int old_flush; /* value of flush param for previous deflate call */
deflate_state *s; deflate_state *s;
if (strm == Z_NULL || strm->state == Z_NULL || if (deflateStateCheck(strm) || flush > Z_BLOCK || flush < 0) {
flush > Z_BLOCK || flush < 0) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
s = strm->state; s = strm->state;
...@@ -973,18 +995,9 @@ int ZEXPORT deflateEnd (strm) ...@@ -973,18 +995,9 @@ int ZEXPORT deflateEnd (strm)
{ {
int status; int status;
if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; if (deflateStateCheck(strm)) return Z_STREAM_ERROR;
status = strm->state->status; status = strm->state->status;
if (status != INIT_STATE &&
status != EXTRA_STATE &&
status != NAME_STATE &&
status != COMMENT_STATE &&
status != HCRC_STATE &&
status != BUSY_STATE &&
status != FINISH_STATE) {
return Z_STREAM_ERROR;
}
/* Deallocate in reverse order of allocations: */ /* Deallocate in reverse order of allocations: */
TRY_FREE(strm, strm->state->pending_buf); TRY_FREE(strm, strm->state->pending_buf);
...@@ -1015,7 +1028,7 @@ int ZEXPORT deflateCopy (dest, source) ...@@ -1015,7 +1028,7 @@ int ZEXPORT deflateCopy (dest, source)
ushf *overlay; ushf *overlay;
if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { if (deflateStateCheck(source) || dest == Z_NULL) {
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
} }
......
...@@ -92,6 +92,7 @@ ...@@ -92,6 +92,7 @@
#endif #endif
/* function prototypes */ /* function prototypes */
local int inflateStateCheck OF((z_streamp strm));
local void fixedtables OF((struct inflate_state FAR *state)); local void fixedtables OF((struct inflate_state FAR *state));
local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
unsigned copy)); unsigned copy));
...@@ -101,12 +102,26 @@ local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, ...@@ -101,12 +102,26 @@ local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
unsigned len)); 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 inflateResetKeep(strm)
z_streamp strm; z_streamp strm;
{ {
struct inflate_state FAR *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; state = (struct inflate_state FAR *)strm->state;
strm->total_in = strm->total_out = state->total = 0; strm->total_in = strm->total_out = state->total = 0;
strm->msg = Z_NULL; strm->msg = Z_NULL;
...@@ -131,7 +146,7 @@ z_streamp strm; ...@@ -131,7 +146,7 @@ z_streamp strm;
{ {
struct inflate_state FAR *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; state = (struct inflate_state FAR *)strm->state;
state->wsize = 0; state->wsize = 0;
state->whave = 0; state->whave = 0;
...@@ -147,7 +162,7 @@ int windowBits; ...@@ -147,7 +162,7 @@ int windowBits;
struct inflate_state FAR *state; struct inflate_state FAR *state;
/* get the 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; state = (struct inflate_state FAR *)strm->state;
/* extract wrap request from windowBits parameter */ /* extract wrap request from windowBits parameter */
...@@ -210,7 +225,9 @@ int stream_size; ...@@ -210,7 +225,9 @@ int stream_size;
if (state == Z_NULL) return Z_MEM_ERROR; if (state == Z_NULL) return Z_MEM_ERROR;
Tracev((stderr, "inflate: allocated\n")); Tracev((stderr, "inflate: allocated\n"));
strm->state = (struct internal_state FAR *)state; strm->state = (struct internal_state FAR *)state;
state->strm = strm;
state->window = Z_NULL; state->window = Z_NULL;
state->mode = HEAD; /* to pass state test in inflateReset2() */
ret = inflateReset2(strm, windowBits); ret = inflateReset2(strm, windowBits);
if (ret != Z_OK) { if (ret != Z_OK) {
ZFREE(strm, state); ZFREE(strm, state);
...@@ -234,7 +251,7 @@ int value; ...@@ -234,7 +251,7 @@ int value;
{ {
struct inflate_state FAR *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; state = (struct inflate_state FAR *)strm->state;
if (bits < 0) { if (bits < 0) {
state->hold = 0; state->hold = 0;
...@@ -625,7 +642,7 @@ int flush; ...@@ -625,7 +642,7 @@ int flush;
static const unsigned short order[19] = /* permutation of code lengths */ 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}; {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)) (strm->next_in == Z_NULL && strm->avail_in != 0))
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
...@@ -1261,7 +1278,7 @@ int ZEXPORT inflateEnd(strm) ...@@ -1261,7 +1278,7 @@ int ZEXPORT inflateEnd(strm)
z_streamp strm; z_streamp strm;
{ {
struct inflate_state FAR *state; 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; return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state; state = (struct inflate_state FAR *)strm->state;
if (state->window != Z_NULL) ZFREE(strm, state->window); if (state->window != Z_NULL) ZFREE(strm, state->window);
...@@ -1279,7 +1296,7 @@ uInt *dictLength; ...@@ -1279,7 +1296,7 @@ uInt *dictLength;
struct inflate_state FAR *state; struct inflate_state FAR *state;
/* check 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; state = (struct inflate_state FAR *)strm->state;
/* copy dictionary */ /* copy dictionary */
...@@ -1304,7 +1321,7 @@ uInt dictLength; ...@@ -1304,7 +1321,7 @@ uInt dictLength;
int ret; int ret;
/* check 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; state = (struct inflate_state FAR *)strm->state;
if (state->wrap != 0 && state->mode != DICT) if (state->wrap != 0 && state->mode != DICT)
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
...@@ -1336,7 +1353,7 @@ gz_headerp head; ...@@ -1336,7 +1353,7 @@ gz_headerp head;
struct inflate_state FAR *state; struct inflate_state FAR *state;
/* check 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; state = (struct inflate_state FAR *)strm->state;
if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
...@@ -1389,7 +1406,7 @@ z_streamp strm; ...@@ -1389,7 +1406,7 @@ z_streamp strm;
struct inflate_state FAR *state; struct inflate_state FAR *state;
/* check parameters */ /* 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; state = (struct inflate_state FAR *)strm->state;
if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
...@@ -1436,7 +1453,7 @@ z_streamp strm; ...@@ -1436,7 +1453,7 @@ z_streamp strm;
{ {
struct inflate_state FAR *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; state = (struct inflate_state FAR *)strm->state;
return state->mode == STORED && state->bits == 0; return state->mode == STORED && state->bits == 0;
} }
...@@ -1451,8 +1468,7 @@ z_streamp source; ...@@ -1451,8 +1468,7 @@ z_streamp source;
unsigned wsize; unsigned wsize;
/* check input */ /* check input */
if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || if (inflateStateCheck(source) || dest == Z_NULL)
source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
return Z_STREAM_ERROR; return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)source->state; state = (struct inflate_state FAR *)source->state;
...@@ -1473,6 +1489,7 @@ z_streamp source; ...@@ -1473,6 +1489,7 @@ z_streamp source;
/* copy state */ /* copy state */
zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
copy->strm = dest;
if (state->lencode >= state->codes && if (state->lencode >= state->codes &&
state->lencode <= state->codes + ENOUGH - 1) { state->lencode <= state->codes + ENOUGH - 1) {
copy->lencode = copy->codes + (state->lencode - state->codes); copy->lencode = copy->codes + (state->lencode - state->codes);
...@@ -1494,7 +1511,7 @@ int subvert; ...@@ -1494,7 +1511,7 @@ int subvert;
{ {
struct inflate_state FAR *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; state = (struct inflate_state FAR *)strm->state;
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
state->sane = !subvert; state->sane = !subvert;
...@@ -1512,7 +1529,7 @@ int check; ...@@ -1512,7 +1529,7 @@ int check;
{ {
struct inflate_state FAR *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; state = (struct inflate_state FAR *)strm->state;
if (check) if (check)
state->wrap |= 4; state->wrap |= 4;
...@@ -1526,7 +1543,7 @@ z_streamp strm; ...@@ -1526,7 +1543,7 @@ z_streamp strm;
{ {
struct inflate_state FAR *state; struct inflate_state FAR *state;
if (strm == Z_NULL || strm->state == Z_NULL) if (inflateStateCheck(strm))
return -(1L << 16); return -(1L << 16);
state = (struct inflate_state FAR *)strm->state; state = (struct inflate_state FAR *)strm->state;
return (long)(((unsigned long)((long)state->back)) << 16) + return (long)(((unsigned long)((long)state->back)) << 16) +
...@@ -1538,7 +1555,7 @@ unsigned long ZEXPORT inflateCodesUsed(strm) ...@@ -1538,7 +1555,7 @@ unsigned long ZEXPORT inflateCodesUsed(strm)
z_streamp strm; z_streamp strm;
{ {
struct inflate_state FAR *state; struct inflate_state FAR *state;
if (strm == Z_NULL || strm->state == Z_NULL) return (unsigned long)0 - 1; if (inflateStateCheck(strm)) return (unsigned long)0 - 1;
state = (struct inflate_state FAR *)strm->state; state = (struct inflate_state FAR *)strm->state;
return (unsigned long)(state->next - state->codes); return (unsigned long)(state->next - state->codes);
} }
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
/* Possible inflate modes between inflate() calls */ /* Possible inflate modes between inflate() calls */
typedef enum { typedef enum {
HEAD, /* i: waiting for magic header */ HEAD = 16180, /* i: waiting for magic header */
FLAGS, /* i: waiting for method and flags (gzip) */ FLAGS, /* i: waiting for method and flags (gzip) */
TIME, /* i: waiting for modification time (gzip) */ TIME, /* i: waiting for modification time (gzip) */
OS, /* i: waiting for extra flags and operating system (gzip) */ OS, /* i: waiting for extra flags and operating system (gzip) */
...@@ -80,6 +80,7 @@ typedef enum { ...@@ -80,6 +80,7 @@ typedef enum {
/* State maintained between inflate() calls -- approximately 7K bytes, not /* State maintained between inflate() calls -- approximately 7K bytes, not
including the allocated sliding window, which is up to 32K bytes. */ including the allocated sliding window, which is up to 32K bytes. */
struct inflate_state { struct inflate_state {
z_streamp strm; /* pointer back to this zlib stream */
inflate_mode mode; /* current inflate mode */ inflate_mode mode; /* current inflate mode */
int last; /* true if processing last block */ int last; /* true if processing last block */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip, int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册