From 615abf58bee3528914aa67ce2be34322cc987d7e Mon Sep 17 00:00:00 2001 From: Jason Gross Date: Wed, 19 Aug 2026 00:19:19 +0000 Subject: [PATCH] inflate: count the header bytes consumed before returning Z_NEED_DICT case DICT: returns via RESTORE(); return Z_NEED_DICT; without reaching inf_leave, the only place total_in is updated. RESTORE() writes the advanced next_in/avail_in back, so the six header and DICTID bytes are never counted and total_in stays six short for the rest of the stream. Re-entering without setting a dictionary adds zero, so the count is not doubled. test/example.c: check total_in against the bytes actually consumed after the dictionary inflate. This fails without the fix. --- inflate.c | 1 + test/example.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/inflate.c b/inflate.c index 5f5d4922b7..f6dcbdad9e 100644 --- a/inflate.c +++ b/inflate.c @@ -700,6 +700,7 @@ int ZEXPORT inflate(z_streamp strm, int flush) { case DICT: if (state->havedict == 0) { RESTORE(); + strm->total_in += in - strm->avail_in; return Z_NEED_DICT; } strm->adler = state->check = adler32(0L, Z_NULL, 0); diff --git a/test/example.c b/test/example.c index 9cc5f763bc..c42b27ede7 100644 --- a/test/example.c +++ b/test/example.c @@ -479,6 +479,11 @@ static void test_dict_inflate(Byte *compr, uLong comprLen, Byte *uncompr, CHECK_ERR(err, "inflate with dict"); } + if (d_stream.total_in != comprLen - d_stream.avail_in) { + fprintf(stderr, "bad total_in after dictionary inflate\n"); + exit(1); + } + err = inflateEnd(&d_stream); CHECK_ERR(err, "inflateEnd");