Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 19 additions & 8 deletions inflate.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,11 @@ int ZEXPORT inflateReset(z_streamp strm) {

if (inflateStateCheck(strm)) return Z_STREAM_ERROR;
state = (struct inflate_state FAR *)strm->state;
state->wsize = 0;
/* Keep wsize when the sliding window allocation is retained so the
window/wsize relationship remains consistent across reset. Clear
wsize only when there is no window. Indices always restart at zero. */
if (state->window == Z_NULL)
state->wsize = 0;
state->whave = 0;
state->wnext = 0;
return inflateResetKeep(strm);
Expand Down Expand Up @@ -162,6 +166,7 @@ int ZEXPORT inflateReset2(z_streamp strm, int windowBits) {
if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
ZFREE(strm, state->window);
state->window = Z_NULL;
state->wsize = 0;
}

/* update state and reset the rest of it */
Expand Down Expand Up @@ -255,16 +260,22 @@ local int updatewindow(z_streamp strm, const Bytef *end, unsigned copy) {

state = (struct inflate_state FAR *)strm->state;

/* if it hasn't been done already, allocate space for the window */
/* if it hasn't been done already, allocate space for the window.
Set capacity (wsize) before binding the pointer so the window/wsize
relationship stays consistent for bounds annotations. */
if (state->window == Z_NULL) {
state->wsize = 1U << state->wbits;
state->wnext = 0;
state->whave = 0;
state->window = (unsigned char FAR *)
ZALLOC(strm, 1U << state->wbits,
sizeof(unsigned char));
if (state->window == Z_NULL) return 1;
ZALLOC(strm, state->wsize, sizeof(unsigned char));
if (state->window == Z_NULL) {
state->wsize = 0;
return 1;
}
}

/* if window not in use yet, initialize */
if (state->wsize == 0) {
else if (state->wsize == 0) {
/* Defensive: allocation present but capacity cleared — restore. */
state->wsize = 1U << state->wbits;
state->wnext = 0;
state->whave = 0;
Expand Down
11 changes: 10 additions & 1 deletion inflate.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,16 @@ struct inflate_state {
unsigned wsize; /* window size or zero if not using window */
unsigned whave; /* valid bytes in the window */
unsigned wnext; /* window write index */
unsigned char FAR *window; /* allocated sliding window, if needed */
/* window <-> wsize: NULL iff wsize == 0. Attribute is inert when the
compiler does not support it (default builds unchanged). */
#if defined(__has_attribute) && __has_attribute(__sized_by_or_null__)
unsigned char FAR *window __attribute__((__sized_by_or_null__(wsize)));
#elif defined(__has_attribute) && __has_attribute(__counted_by_or_null__)
unsigned char FAR *window __attribute__((__counted_by_or_null__(wsize)));
#else
unsigned char FAR *window;
#endif
/* allocated sliding window, if needed */
/* bit accumulator */
unsigned long hold; /* input bit accumulator */
unsigned bits; /* number of bits in hold */
Expand Down