From fe1c1a8c2f72a6bcb10fda953b47f44bba2065a9 Mon Sep 17 00:00:00 2001 From: Brandon Barrante Date: Sun, 6 Sep 2026 20:26:43 +0000 Subject: [PATCH] gzip: initialise state->past for write handles too, not just read handles gz_reset() left state->past uninitialised in write mode. gz_open() allocates gz_state with malloc() rather than calloc(), so a write-mode handle read the field out of indeterminate heap. Since a4e4521 both gzseek64() and gztell64() dereference past in either mode, so the uninitialised byte silently controlled whether two consecutive SEEK_CUR seeks folded their pending skip into the next offset. When the byte came up non-zero, the first seek s zero-fill was lost and the produced gzip stream was well-formed with a valid CRC and the wrong contents; gztell() likewise returned the wrong position after a deferred seek. Move the past = 0 assignment out of the GZ_READ branch so both read and write handles start with it zeroed. No struct or ABI change. Fixes: madler#1303 Reported-by: jxravi (github.com/jxravi) Signed-off-by: Brandon Barrante --- gzlib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gzlib.c b/gzlib.c index 7a37a96cf0..67900b661b 100644 --- a/gzlib.c +++ b/gzlib.c @@ -68,9 +68,9 @@ char ZLIB_INTERNAL *gz_strwinerror(DWORD error) { /* Reset gzip file state */ local void gz_reset(gz_statep state) { state->x.have = 0; /* no output data available */ + state->past = 0; /* have not read past end yet */ if (state->mode == GZ_READ) { /* for reading ... */ state->eof = 0; /* not at end of file */ - state->past = 0; /* have not read past end yet */ state->how = LOOK; /* look for gzip header */ state->junk = -1; /* mark first member */ }