From 3f96dcdd414f0ac578d7e2c507f93c35f58a3164 Mon Sep 17 00:00:00 2001 From: Samuel Giddins Date: Fri, 23 Oct 2026 22:12:09 -0700 Subject: [PATCH] Keep the arguments of GzipReader#each_line when returning an enumerator rb_gzreader_each created the enumerator with RETURN_ENUMERATOR(obj, 0, 0), so each_line(sep, limit) without a block iterated with the default separator and no limit. ```ruby gz = Zlib.gzip("a,b,c\nd,e\n") Zlib::GzipReader.new(StringIO.new(gz)).each_line(",").to_a # expected: ["a,", "b,", "c\nd,", "e\n"] # actual: ["a,b,c\n", "d,e\n"] ``` Co-Authored-By: Claude Mythos 5.1 --- ext/zlib/zlib.c | 2 +- test/zlib/test_zlib.rb | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 982933b..1901755 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -4559,7 +4559,7 @@ rb_gzreader_each(int argc, VALUE *argv, VALUE obj) { VALUE str; - RETURN_ENUMERATOR(obj, 0, 0); + RETURN_ENUMERATOR(obj, argc, argv); while (!NIL_P(str = gzreader_gets(argc, argv, obj))) { rb_yield(str); diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb index 1f9cb81..df5bc5e 100644 --- a/test/zlib/test_zlib.rb +++ b/test/zlib/test_zlib.rb @@ -1367,6 +1367,15 @@ def test_reader_wrap } end + def test_each_line_enumerator_arguments + # each_line(sep, limit) without a block must keep its arguments + s = Zlib.gzip("a,b,c\nd,e\n") + assert_equal(["a,", "b,", "c\nd,", "e\n"], Zlib::GzipReader.new(StringIO.new(s)).each_line(",").to_a) + assert_equal(["a,b", ",c\n", "d,e", "\n"], Zlib::GzipReader.new(StringIO.new(s)).each_line(3).to_a) + assert_equal(["a,", "b,", "c\n", "d,", "e\n"], Zlib::GzipReader.new(StringIO.new(s)).each_line(",", 2).to_a) + assert_equal(["a,", "b,"], Zlib::GzipReader.new(StringIO.new(s)).each(",").first(2)) + end + def test_corrupted_header gz = Zlib::GzipWriter.new(StringIO.new(s = "".dup)) gz.orig_name = "X"