diff options
| -rw-r--r-- | inflate.c | 14 | ||||
| -rw-r--r-- | inflate.h | 3 | ||||
| -rw-r--r-- | test/example.c | 5 | ||||
| -rw-r--r-- | test/fuzz/example_flush_fuzzer.c | 5 |
4 files changed, 16 insertions, 11 deletions
@@ -67,6 +67,7 @@ int ZEXPORT PREFIX(inflateResetKeep)(PREFIX3(stream) *strm) { state->check = functable.adler32(0L, NULL, 0); state->last = 0; state->havedict = 0; + state->flags = -1; state->dmax = 32768U; state->head = NULL; state->hold = 0; @@ -420,7 +421,6 @@ int ZEXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int flush) { state->mode = FLAGS; break; } - state->flags = 0; /* expect zlib header */ if (state->head != NULL) state->head->done = -1; if (!(state->wrap & 1) || /* check if zlib header allowed */ @@ -447,6 +447,7 @@ int ZEXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int flush) { break; } state->dmax = 1U << len; + state->flags = 0; /* indicate zlib header */ Tracev((stderr, "inflate: zlib header ok\n")); strm->adler = state->check = functable.adler32(0L, NULL, 0); state->mode = hold & 0x200 ? DICTID : TYPE; @@ -1039,7 +1040,7 @@ int ZEXPORT PREFIX(inflate)(PREFIX3(stream) *strm, int flush) { case LENGTH: if (state->wrap && state->flags) { NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { + if ((state->wrap & 4) && hold != (state->total & 0xffffffff)) { strm->msg = (char *)"incorrect length check"; state->mode = BAD; break; @@ -1209,6 +1210,7 @@ static uint32_t syncsearch(uint32_t *have, const unsigned char *buf, uint32_t le int ZEXPORT PREFIX(inflateSync)(PREFIX3(stream) *strm) { unsigned len; /* number of bytes to look at or looked at */ + int flags; /* temporary to save header status */ size_t in, out; /* temporary to save total_in and total_out */ unsigned char buf[4]; /* to restore bit buffer to byte string */ struct inflate_state *state; @@ -1244,13 +1246,17 @@ int ZEXPORT PREFIX(inflateSync)(PREFIX3(stream) *strm) { /* return no joy or set up to restart inflate() on a new block */ if (state->have != 4) return Z_DATA_ERROR; - if (state->mode == HEAD) - state->wrap = 0; /* never processed header, so assume raw */ + if (state->flags == -1) + state->wrap = 0; /* if no header yet, treat as raw */ + else + state->wrap &= ~4; /* no point in computing a check value now */ + flags = state->flags; in = strm->total_in; out = strm->total_out; PREFIX(inflateReset)(strm); strm->total_in = in; strm->total_out = out; + state->flags = flags; state->mode = TYPE; return Z_OK; } @@ -89,7 +89,8 @@ struct inflate_state { int wrap; /* bit 0 true for zlib, bit 1 true for gzip, bit 2 true to validate check value */ int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ + int flags; /* gzip header method and flags, 0 if zlib, or + -1 if raw or no header yet */ unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ unsigned long check; /* protected copy of check value */ unsigned long total; /* protected copy of output count */ diff --git a/test/example.c b/test/example.c index cb9e87a390..8309178e0d 100644 --- a/test/example.c +++ b/test/example.c @@ -451,9 +451,8 @@ void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, si CHECK_ERR(err, "inflateSync"); err = PREFIX(inflate)(&d_stream, Z_FINISH); - if (err != Z_DATA_ERROR) { - fprintf(stderr, "inflate should report DATA_ERROR\n"); - /* Because of incorrect adler32 */ + if (err != Z_STREAM_END) { + fprintf(stderr, "inflate should report Z_STREAM_END\n"); exit(1); } err = PREFIX(inflateEnd)(&d_stream); diff --git a/test/fuzz/example_flush_fuzzer.c b/test/fuzz/example_flush_fuzzer.c index e53ceeca33..bb9f47956e 100644 --- a/test/fuzz/example_flush_fuzzer.c +++ b/test/fuzz/example_flush_fuzzer.c @@ -88,9 +88,8 @@ void test_sync(unsigned char *compr, size_t comprLen, unsigned char *uncompr, si CHECK_ERR(err, "inflateSync"); err = PREFIX(inflate)(&d_stream, Z_FINISH); - if (err != Z_DATA_ERROR) { - fprintf(stderr, "inflate should report DATA_ERROR\n"); - /* Because of incorrect adler32 */ + if (err != Z_STREAM_END) { + fprintf(stderr, "inflate should report Z_STREAM_END\n"); exit(1); } err = PREFIX(inflateEnd)(&d_stream); |
