summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/zlib/zlib.c3
-rw-r--r--test/zlib/test_zlib.rb32
2 files changed, 35 insertions, 0 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index dc608ee460..fe03072576 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -3500,6 +3500,9 @@ static VALUE
rb_gzfile_eof_p(VALUE obj)
{
struct gzfile *gz = get_gzfile(obj);
+ while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) == 0) {
+ gzfile_read_more(gz, Qnil);
+ }
return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
}
diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb
index 779c583424..502ccceec5 100644
--- a/test/zlib/test_zlib.rb
+++ b/test/zlib/test_zlib.rb
@@ -1205,6 +1205,38 @@ if defined? Zlib
}
end
+ # Various methods of Zlib::GzipReader failed when to reading files
+ # just a few bytes larger than GZFILE_READ_SIZE.
+ def test_gzfile_read_size_boundary
+ Tempfile.create("test_zlib_gzip_read_size_boundary") {|t|
+ t.close
+ # NO_COMPRESSION helps with recreating the error condition.
+ # The error happens on compressed files too, but it's harder to reproduce.
+ # For example, ~12750 bytes are needed to trigger the error using __FILE__.
+ # We avoid this because the test file will change over time.
+ Zlib::GzipWriter.open(t.path, Zlib::NO_COMPRESSION) do |gz|
+ gz.print("\n" * 2024) # range from 2024 to 2033 triggers the error
+ gz.flush
+ end
+
+ Zlib::GzipReader.open(t.path) do |f|
+ f.readpartial(1024) until f.eof?
+ assert_raise(EOFError) { f.readpartial(1) }
+ end
+
+ Zlib::GzipReader.open(t.path) do |f|
+ f.readline until f.eof?
+ assert_raise(EOFError) { f.readline }
+ end
+
+ Zlib::GzipReader.open(t.path) do |f|
+ b = f.readbyte until f.eof?
+ f.ungetbyte(b)
+ f.readbyte
+ assert_raise(EOFError) { f.readbyte }
+ end
+ }
+ end
end
class TestZlibGzipWriter < Test::Unit::TestCase