Commit 40e399f for zlib
commit 40e399f1ee97b923058e4662456d941f51d1c9a4
Author: Mark Adler <git@madler.net>
Date: Mon Oct 26 14:16:57 2026 -0700
Restore the requested wrap on inflateReset() after inflateSync().
inflateSync() changes the wrap state for the remainder of the
stream, to treat a stream with no header yet as raw, or, if a
header was seen, to stop verifying the check value. inflateReset()
did not undo that. As a result, after an inflateSync() and an
inflateReset(), later zlib or gzip streams either failed to decode,
or were decoded without verifying their check values, so that
corrupted data was silently accepted. Save the requested wrap, as
is now done for the window size, and restore it on reset.
inflateValidate() updates the saved value so that its setting
persists across resets as before.
diff --git a/inflate.c b/inflate.c
index 95bed57..5f8b93c 100644
--- a/inflate.c
+++ b/inflate.c
@@ -134,6 +134,7 @@ int ZEXPORT inflateReset(z_streamp strm) {
}
state->wbits = state->reqbits;
}
+ state->wrap = state->reqwrap;
state->wsize = 0;
state->whave = 0;
state->wnext = 0;
@@ -172,7 +173,7 @@ int ZEXPORT inflateReset2(z_streamp strm, int windowBits) {
}
/* update state and reset the rest of it */
- state->wrap = wrap;
+ state->reqwrap = state->wrap = wrap;
state->reqbits = state->wbits = (unsigned)windowBits;
return inflateReset(strm);
}
@@ -1304,15 +1305,15 @@ int ZEXPORT inflateSync(z_streamp strm) {
/* return no joy or set up to restart inflate() on a new block */
if (state->have != 4) return Z_DATA_ERROR;
- 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;
inflateReset(strm);
strm->total_in = in; strm->total_out = out;
state->flags = flags;
+ if (flags == -1)
+ state->wrap = 0; /* if no header yet, treat as raw */
+ else
+ state->wrap &= ~4; /* no point in computing a check value now */
if (state->wbits == 0) {
/* we never got to see a header for the window size -- set to max */
if (state->window != Z_NULL) {
@@ -1415,6 +1416,10 @@ int ZEXPORT inflateValidate(z_streamp strm, int check) {
state->wrap |= 4;
else
state->wrap &= ~4;
+ if (check && state->reqwrap)
+ state->reqwrap |= 4;
+ else
+ state->reqwrap &= ~4;
return Z_OK;
}
diff --git a/inflate.h b/inflate.h
index 7fde4d1..e7dfc8e 100644
--- a/inflate.h
+++ b/inflate.h
@@ -85,6 +85,7 @@ struct inflate_state {
int last; /* true if processing last block */
int wrap; /* bit 0 true for zlib, bit 1 true for gzip,
bit 2 true to validate check value */
+ int reqwrap; /* requested wrap */
int havedict; /* true if dictionary provided */
int flags; /* gzip header method and flags, 0 if zlib, or
-1 if raw or no header yet */