diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index f13ef4d..a3c9fd4 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)); @@ -2341,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) 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") }