Skip to content

Commit 437bea8

Browse files
committed
In Zlib::GzipReader#eof? check if we're actually at eof
Only consider it eof if we read ahead and something fills the buf. If not, we may only have empty blocks and the footer. Fixes #56
1 parent a8fe482 commit 437bea8

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

ext/zlib/zlib.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3500,6 +3500,9 @@ static VALUE
35003500
rb_gzfile_eof_p(VALUE obj)
35013501
{
35023502
struct gzfile *gz = get_gzfile(obj);
3503+
while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) == 0) {
3504+
gzfile_read_more(gz, Qnil);
3505+
}
35033506
return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
35043507
}
35053508

test/zlib/test_zlib.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,6 +1205,38 @@ def test_double_close
12051205
}
12061206
end
12071207

1208+
# Various methods of Zlib::GzipReader failed when to reading files
1209+
# just a few bytes larger than GZFILE_READ_SIZE.
1210+
def test_gzfile_read_size_boundary
1211+
Tempfile.create("test_zlib_gzip_read_size_boundary") {|t|
1212+
t.close
1213+
# NO_COMPRESSION helps with recreating the error condition.
1214+
# The error happens on compressed files too, but it's harder to reproduce.
1215+
# For example, ~12750 bytes are needed to trigger the error using __FILE__.
1216+
# We avoid this because the test file will change over time.
1217+
Zlib::GzipWriter.open(t.path, Zlib::NO_COMPRESSION) do |gz|
1218+
gz.print("\n" * 2024) # range from 2024 to 2033 triggers the error
1219+
gz.flush
1220+
end
1221+
1222+
Zlib::GzipReader.open(t.path) do |f|
1223+
f.readpartial(1024) until f.eof?
1224+
assert_raise(EOFError) { f.readpartial(1) }
1225+
end
1226+
1227+
Zlib::GzipReader.open(t.path) do |f|
1228+
f.readline until f.eof?
1229+
assert_raise(EOFError) { f.readline }
1230+
end
1231+
1232+
Zlib::GzipReader.open(t.path) do |f|
1233+
b = f.readbyte until f.eof?
1234+
f.ungetbyte(b)
1235+
f.readbyte
1236+
assert_raise(EOFError) { f.readbyte }
1237+
end
1238+
}
1239+
end
12081240
end
12091241

12101242
class TestZlibGzipWriter < Test::Unit::TestCase

0 commit comments

Comments
 (0)