diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index f13ef4d..966c280 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -4338,7 +4338,7 @@ gzreader_skip_linebreaks(struct gzfile *gz) static void rscheck(const char *rsptr, rb_len_t rslen, VALUE rs) { - if (RSTRING_PTR(rs) != rsptr && RSTRING_LEN(rs) != rslen) + if (RSTRING_PTR(rs) != rsptr || RSTRING_LEN(rs) != rslen) rb_raise(rb_eRuntimeError, "rs modified"); } diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb index e1ecbf8..2a985ec 100644 --- a/test/zlib/test_zlib.rb +++ b/test/zlib/test_zlib.rb @@ -987,6 +987,19 @@ def test_read0 assert_equal("", Zlib::GzipReader.new(StringIO.new(D0)).read(0)) end + def test_gets_separator_modified_by_io + rs = "-" * 1000 + src = StringIO.new(Zlib.gzip(Random.new(0).bytes(200_000).tr("-", "x") + rs)) + n = 0 + io = Object.new + io.define_singleton_method(:readpartial) do |len, buf = nil| + (rs.clear << "-" * 1000) if (n += 1) == 300 + src.readpartial([len, 100].min, *buf) + end + gz = Zlib::GzipReader.new(io) + assert_raise_with_message(RuntimeError, "rs modified") { gz.gets(rs) } + end + def test_ungetc s = "".dup w = Zlib::GzipWriter.new(StringIO.new(s))