Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion ext/zlib/zlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1216,6 +1216,8 @@ zstream_run_try(VALUE value_arg)
}
}
}
z->stream.next_in = Z_NULL;
z->stream.avail_in = 0;
raise_zlib_error(err, z->stream.msg);
}

Expand All @@ -1225,6 +1227,9 @@ zstream_run_try(VALUE value_arg)
if (!NIL_P(old_input)) {
rb_str_resize(old_input, 0);
}
/* the rest is in z->input now; do not leave next_in in old_input */
z->stream.next_in = Z_NULL;
z->stream.avail_in = 0;

return Qnil;
}
Expand Down Expand Up @@ -2144,7 +2149,8 @@ do_inflate(struct zstream *z, VALUE src)
return;
}
StringValue(src);
if (RSTRING_LEN(src) > 0 || z->stream.avail_in > 0) { /* prevent Z_BUF_ERROR */
if (RSTRING_LEN(src) > 0 ||
(!NIL_P(z->input) && RSTRING_LEN(z->input) > 0)) { /* prevent Z_BUF_ERROR */
zstream_run(z, (Bytef*)RSTRING_PTR(src), RSTRING_LEN(src), Z_SYNC_FLUSH);
}
}
Expand Down
50 changes: 50 additions & 0 deletions test/zlib/test_zlib.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,38 @@ def test_deflate_chunked_break
assert_equal input, original
end

def test_params_after_chunked_break
chunks = []
r = Random.new 0

# small enough that params can flush what zlib holds without Z_BUF_ERROR
z = Zlib::Deflate.new(Zlib::DEFAULT_COMPRESSION, 9, 1)

input = r.bytes(20000)
z.deflate(input) do |chunk|
chunks << chunk
break
end

assert_operator 0, :<, z.avail_in

z.params(Zlib::BEST_SPEED, Zlib::FILTERED)
chunks << z.finish

assert_equal input, Zlib.inflate(chunks.join)
end

def test_params_after_failed_deflate
z = Zlib::Deflate.new
z << "foo"
assert_raise(Zlib::StreamError) { z.deflate("bar", 10000) }
assert_equal "bar", z.flush_next_in

z.params(Zlib::BEST_SPEED, Zlib::FILTERED)

assert_equal "foo", Zlib::Inflate.inflate(z.finish)
end

def test_addstr
z = Zlib::Deflate.new
z << "foo"
Expand Down Expand Up @@ -620,6 +652,24 @@ def test_inflate_dictionary
assert_equal "foofoofoo", out
end

def test_inflate_empty_after_chunked_break
chunks = []
input = Random.new(0).bytes(20000)

z = Zlib::Inflate.new

z.inflate(Zlib.deflate(input)) do |chunk|
chunks << chunk
break
end

assert_operator 0, :<, z.avail_in

chunks << z.inflate("")

assert_equal input, chunks.join
end

def test_sync
z = Zlib::Deflate.new
s = z.deflate("foo" * 1000, Zlib::FULL_FLUSH)
Expand Down
Loading