Skip to content

Commit 4bf64d5

Browse files
committed
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]
1 parent a35268a commit 4bf64d5

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

ext/stringio/stringio.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1181,7 +1181,7 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
11811181
const char *s, *e, *p;
11821182
long n, limit = arg->limit;
11831183
VALUE str = arg->rs;
1184-
int w = 0;
1184+
long w = 0;
11851185
rb_encoding *enc = get_enc(ptr);
11861186

11871187
if (ptr->pos >= (n = RSTRING_LEN(ptr->string))) {
@@ -1237,7 +1237,8 @@ strio_getline(struct getline_arg *arg, struct StringIO *ptr)
12371237
if (e - s < 1024) {
12381238
for (p = s; p + n <= e; ++p) {
12391239
if (MEMCMP(p, RSTRING_PTR(str), char, n) == 0) {
1240-
e = p + (arg->chomp ? 0 : n);
1240+
e = p + n;
1241+
w = (arg->chomp ? n : 0);
12411242
break;
12421243
}
12431244
}

test/stringio/test_stringio.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,13 @@ def o.to_str; "z"; end
584584
end
585585
end
586586

587+
def test_each_string_sep
588+
f = StringIO.new('a||b||c')
589+
assert_equal(["a||", "b||", "c"], f.each("||").to_a)
590+
f.rewind
591+
assert_equal(["a", "b", "c"], f.each("||", chomp: true).to_a)
592+
end
593+
587594
def test_each
588595
f = StringIO.new("foo\nbar\nbaz\n")
589596
assert_equal(["foo\n", "bar\n", "baz\n"], f.each.to_a)

0 commit comments

Comments
 (0)