ruby-changes:72007
From: Jeremy <ko1@a...>
Date: Mon, 30 May 2022 12:55:56 +0900 (JST)
Subject: [ruby-changes:72007] 1f82269f4e (master): [ruby/stringio] Fix each with multiple character string and chomp
https://git.ruby-lang.org/ruby.git/commit/?id=1f82269f4e From 1f82269f4e1bf037e3e5504c6071b905f26fec6f Mon Sep 17 00:00:00 2001 From: Jeremy Evans <code@j...> Date: Thu, 26 May 2022 15:22:28 -0700 Subject: [ruby/stringio] Fix each with multiple character string and chomp Previously, this could result in an infinite loop. Always update the e pointer in this case, setting w when chomping so the chomped data is not included in the output. Fixes [Bug #18769] https://github.com/ruby/stringio/commit/4bf64d5130 --- ext/stringio/stringio.c | 5 +++-- test/stringio/test_stringio.rb | 7 +++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c index f452bd0da0..04ca25b0b8 100644 --- a/ext/stringio/stringio.c +++ b/ext/stringio/stringio.c @@ -1181,7 +1181,7 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr) https://github.com/ruby/ruby/blob/trunk/ext/stringio/stringio.c#L1181 const char *s, *e, *p; long n, limit = arg->limit; VALUE str = arg->rs; - int w = 0; + long w = 0; rb_encoding *enc = get_enc(ptr); if (ptr->pos >= (n = RSTRING_LEN(ptr->string))) { @@ -1237,7 +1237,8 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr) https://github.com/ruby/ruby/blob/trunk/ext/stringio/stringio.c#L1237 if (e - s < 1024) { for (p = s; p + n <= e; ++p) { if (MEMCMP(p, RSTRING_PTR(str), char, n) == 0) { - e = p + (arg->chomp ? 0 : n); + e = p + n; + w = (arg->chomp ? n : 0); break; } } diff --git a/test/stringio/test_stringio.rb b/test/stringio/test_stringio.rb index 144a9f4292..f14b65a8ea 100644 --- a/test/stringio/test_stringio.rb +++ b/test/stringio/test_stringio.rb @@ -584,6 +584,13 @@ class TestStringIO < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/stringio/test_stringio.rb#L584 end end + def test_each_string_sep + f = StringIO.new('a||b||c') + assert_equal(["a||", "b||", "c"], f.each("||").to_a) + f.rewind + assert_equal(["a", "b", "c"], f.each("||", chomp: true).to_a) + end + def test_each f = StringIO.new("foo\nbar\nbaz\n") assert_equal(["foo\n", "bar\n", "baz\n"], f.each.to_a) -- cgit v1.2.1 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/