diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 982933b..14b4d58 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -1212,11 +1212,14 @@ zstream_run_try(VALUE value_arg) VALUE dict = rb_hash_aref(dicts, rb_uint2inum(z->stream.adler)); if (!NIL_P(dict)) { rb_inflate_set_dictionary(self, dict); - goto loop; + if (z->stream.avail_in > 0) goto loop; + /* the dictionary id was the last byte available; inflate() + * would only report Z_BUF_ERROR now */ + err = Z_OK; } } } - raise_zlib_error(err, z->stream.msg); + if (err != Z_OK) raise_zlib_error(err, z->stream.msg); } if (z->stream.avail_in > 0) { diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb index 1f9cb81..15cf4a4 100644 --- a/test/zlib/test_zlib.rb +++ b/test/zlib/test_zlib.rb @@ -283,6 +283,22 @@ def test_add_dictionary assert_equal "foofoofoo", out end + def test_add_dictionary_byte_at_a_time + dict = "hello world" + d = Zlib::Deflate.new + d.set_dictionary(dict) + deflated = d.deflate("hello", Zlib::FINISH) + d.close + z = Zlib::Inflate.new + z.add_dictionary(dict) + out = "".dup + # feeding the byte that completes the dictionary id used to raise BufError + deflated.each_byte { |b| out << z.inflate(b.chr) } + out << z.finish + assert_equal("hello", out) + z.close + end + def test_finish_chunked # zeros = Zlib::Deflate.deflate("0" * 100_000) zeros = "x\234\355\3011\001\000\000\000\302\240J\353\237\316\032\036@" \