mirror of
https://github.com/ruby/ruby.git
synced 2026-10-28 16:36:20 +08:00
Fix buffer overflow in Array#values_at
Array#values_at can execute arbitrary code during execution which may
modify the source array. This can cause a buffer overflow if the new length
of the array has decreased. The following script crashes:
a = (0..100_000).to_a
obj = Object.new
obj.define_singleton_method(:begin) do
a.clear
0
end
obj.define_singleton_method(:end) { 10_000 }
obj.define_singleton_method(:exclude_end?) { false }
puts a.values_at(obj).length
This commit is contained in:
1 parent
18ac8cd1d5
commit
3f6143715a
2 files changed
+15
Notes:
git
2026-09-17 00:01:47 +00:00
No files matched your search
@@ -3963,6 +3963,9 @@ append_values_at_single(VALUE result, VALUE ary, long olen, VALUE idx)
|
||||
/* check if idx is Range */
|
||||
else if (rb_range_beg_len(idx, &beg, &len, olen, 1)) {
|
||||
if (len > 0) {
|
||||
// rb_range_beg_len may run arbitrary code that modifies ary, so we
|
||||
// need to re-calculate olen
|
||||
const long olen = RARRAY_LEN(ary);
|
||||
const VALUE *const src = RARRAY_CONST_PTR(ary);
|
||||
const long end = beg + len;
|
||||
const long prevlen = RARRAY_LEN(result);
|
||||
|
||||
@@ -2977,6 +2977,18 @@ class TestArray < Test::Unit::TestCase
|
||||
assert_equal([nil], a.values_at(2**31-1))
|
||||
end
|
||||
|
||||
def test_values_at_ary_modify
|
||||
a = (0..100_000).to_a
|
||||
obj = Object.new
|
||||
obj.define_singleton_method(:begin) do
|
||||
a.clear
|
||||
0
|
||||
end
|
||||
obj.define_singleton_method(:end) { 10_000 }
|
||||
obj.define_singleton_method(:exclude_end?) { false }
|
||||
assert_equal(10_001, a.values_at(obj).length)
|
||||
end
|
||||
|
||||
def test_select
|
||||
assert_equal([0, 2], [0, 1, 2, 3].select {|x| x % 2 == 0 })
|
||||
end
|
||||
|
||||
Reference in new issue
Block a user