Skip to content

Commit fa85d23

Browse files
committed
[Bug #21380] Prohibit modification in String#split block
Reported at https://hackerone.com/reports/3163876
1 parent 7082ef2 commit fa85d23

2 files changed

Lines changed: 14 additions & 4 deletions

File tree

string.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9748,11 +9748,15 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
97489748
}
97499749
}
97509750

9751-
#define SPLIT_STR(beg, len) (empty_count = split_string(result, str, beg, len, empty_count))
9751+
#define SPLIT_STR(beg, len) ( \
9752+
empty_count = split_string(result, str, beg, len, empty_count), \
9753+
str_mod_check(str, str_start, str_len))
97529754

97539755
beg = 0;
97549756
char *ptr = RSTRING_PTR(str);
9755-
char *eptr = RSTRING_END(str);
9757+
char *const str_start = ptr;
9758+
const long str_len = RSTRING_LEN(str);
9759+
char *const eptr = str_start + str_len;
97569760
if (split_type == SPLIT_TYPE_AWK) {
97579761
char *bptr = ptr;
97589762
int skip = 1;
@@ -9813,7 +9817,6 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
98139817
}
98149818
}
98159819
else if (split_type == SPLIT_TYPE_STRING) {
9816-
char *str_start = ptr;
98179820
char *substr_start = ptr;
98189821
char *sptr = RSTRING_PTR(spat);
98199822
long slen = RSTRING_LEN(spat);
@@ -9830,14 +9833,14 @@ rb_str_split_m(int argc, VALUE *argv, VALUE str)
98309833
continue;
98319834
}
98329835
SPLIT_STR(substr_start - str_start, (ptr+end) - substr_start);
9836+
str_mod_check(spat, sptr, slen);
98339837
ptr += end + slen;
98349838
substr_start = ptr;
98359839
if (!NIL_P(limit) && lim <= ++i) break;
98369840
}
98379841
beg = ptr - str_start;
98389842
}
98399843
else if (split_type == SPLIT_TYPE_CHARS) {
9840-
char *str_start = ptr;
98419844
int n;
98429845

98439846
if (result) result = rb_ary_new_capa(RSTRING_LEN(str));

test/ruby/test_string.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,6 +1869,13 @@ def test_split_with_block
18691869

18701870
result = []; S("aaa,bbb,ccc,ddd").split(/,/) {|s| result << s.gsub(/./, "A")}
18711871
assert_equal(["AAA"]*4, result)
1872+
1873+
s = S("abc ") * 20
1874+
assert_raise(RuntimeError) {
1875+
10.times do
1876+
s.split {s.prepend("xxx" * 100)}
1877+
end
1878+
}
18721879
ensure
18731880
EnvUtil.suppress_warning {$; = fs}
18741881
end

0 commit comments

Comments
 (0)