summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--inflate.c14
-rw-r--r--inflate.h3
-rw-r--r--test/example.c5
-rw-r--r--test/fuzz/example_flush_fuzzer.c5
4 files changed, 16 insertions, 11 deletions
diff --git a/inflate.c b/inflate.c
index 0b17e318d1..2ba094798f 100644
--- a/inflate.c
+++ b/inflate.c
@@ -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;
}
diff --git a/inflate.h b/inflate.h
index 846fcdcf32..384459ab24 100644
--- a/inflate.h
+++ b/inflate.h
@@ -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);