зеркало из https://github.com/github/ruby.git
Prevent segfault in String#scan with ObjectSpace.each_object
Calling `String#scan` without a block creates an incomplete MatchData object whose `RMATCH(match)->str` is Qfalse. Usually this object is not leaked, but it was possible to pull it by using ObjectSpace.each_object. This change hides the internal MatchData object by using rb_obj_hide. Fixes [Bug #19159]
This commit is contained in:
Родитель
f0c9d2a0c8
Коммит
ab4c7077cc
7
re.c
7
re.c
|
@ -1739,6 +1739,13 @@ rb_reg_search_set_match(VALUE re, VALUE str, long pos, int reverse, int set_back
|
|||
if (set_backref_str) {
|
||||
RMATCH(match)->str = rb_str_new4(str);
|
||||
}
|
||||
else {
|
||||
/* Note that a MatchData object with RMATCH(match)->str == 0 is incomplete!
|
||||
* We need to hide the object from ObjectSpace.each_object.
|
||||
* https://bugs.ruby-lang.org/issues/19159
|
||||
*/
|
||||
rb_obj_hide(match);
|
||||
}
|
||||
|
||||
RMATCH(match)->regexp = re;
|
||||
rb_backref_set(match);
|
||||
|
|
|
@ -1601,6 +1601,15 @@ CODE
|
|||
assert_equal(%w[1 2 3], S("a1 a2 a3").scan(/a\K./))
|
||||
end
|
||||
|
||||
def test_scan_segv
|
||||
bug19159 = '[Bug #19159]'
|
||||
assert_nothing_raised(Exception, bug19159) do
|
||||
ObjectSpace.each_object(MatchData).to_a
|
||||
"".scan(//)
|
||||
ObjectSpace.each_object(MatchData).to_a.inspect
|
||||
end
|
||||
end
|
||||
|
||||
def test_size
|
||||
assert_equal(0, S("").size)
|
||||
assert_equal(4, S("1234").size)
|
||||
|
|
Загрузка…
Ссылка в новой задаче