From f7822c93e71807ff0e5e17e38ec9cb9de686b491 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sun, 25 Oct 2026 07:52:30 +0900 Subject: [PATCH 1/2] Raise InProgressError from Zlib::Inflate#sync during inflate Called from the block of Zlib::Inflate#inflate, #sync pointed next_in at its argument, and the inflate loop kept reading from there after the block returned. Co-Authored-By: Claude Opus 5.5 --- ext/zlib/zlib.c | 4 ++++ test/zlib/test_zlib.rb | 13 +++++++++++++ 2 files changed, 17 insertions(+) diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index f13ef4d..65291c0 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -1265,6 +1265,10 @@ zstream_sync(struct zstream *z, Bytef *src, rb_len_t len) /* VALUE rest; */ int err; + if (z->flags & ZSTREAM_IN_PROGRESS) { + rb_raise(cInProgressError, "zlib stream is in progress"); + } + if (!NIL_P(z->input)) { z->stream.next_in = (Bytef*)RSTRING_PTR(z->input); z->stream.avail_in = MAX_UINT(RSTRING_LEN(z->input)); diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb index e1ecbf8..803642c 100644 --- a/test/zlib/test_zlib.rb +++ b/test/zlib/test_zlib.rb @@ -647,6 +647,19 @@ def test_sync assert_equal(true, z.sync("\0" * 100 + s)) end + def test_sync_in_progress + src = "x" * 100_000 + z = Zlib::Inflate.new + inflated = "".dup + z.inflate(Zlib.deflate(src)) do |chunk| + if inflated.empty? + assert_raise(Zlib::InProgressError) { z.sync("\0\0\xff\xff".b) } + end + inflated << chunk + end + assert_equal src, inflated + end + def test_set_dictionary z = Zlib::Inflate.new assert_raise(Zlib::StreamError) { z.set_dictionary("foo") } From bbff886734541712fd5315d82e2cf3ba0f433f06 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Sun, 25 Oct 2026 09:36:35 +0900 Subject: [PATCH 2/2] Fix the rdoc of Zlib::Inflate#sync It described the return values the other way around, and did not mention Zlib::InProgressError. Co-Authored-By: Claude Opus 5.5 --- ext/zlib/zlib.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 65291c0..a3c9fd4 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -2345,8 +2345,11 @@ rb_inflate_addstr(VALUE obj, VALUE src) * * Inputs +string+ into the end of input buffer and skips data until a full * flush point can be found. If the point is found in the buffer, this method - * flushes the buffer and returns false. Otherwise it returns +true+ and the - * following data of full flush point is preserved in the buffer. + * returns +true+ and the following data of full flush point is preserved in + * the buffer. Otherwise it flushes the buffer and returns +false+. + * + * Raises a Zlib::InProgressError exception if called while the stream is + * being inflated. */ static VALUE rb_inflate_sync(VALUE obj, VALUE src)