Handle mutation of array being merged into set
Check length of array during every iteration, as a #hash method could truncate the array, resulting in heap-use-after-free. Fixes [Bug #21305]
This commit is contained in:
parent
f3246ccebb
commit
be665cf855
Notes:
git
2025-05-03 19:11:32 +00:00
10
set.c
10
set.c
@ -1120,14 +1120,10 @@ set_merge_enum_into(VALUE set, VALUE arg)
|
|||||||
set_iter(arg, set_merge_i, (st_data_t)&args);
|
set_iter(arg, set_merge_i, (st_data_t)&args);
|
||||||
}
|
}
|
||||||
else if (RB_TYPE_P(arg, T_ARRAY)) {
|
else if (RB_TYPE_P(arg, T_ARRAY)) {
|
||||||
long len = RARRAY_LEN(arg);
|
long i;
|
||||||
if (RARRAY_LEN(arg) != 0) {
|
|
||||||
set_table *into = RSET_TABLE(set);
|
set_table *into = RSET_TABLE(set);
|
||||||
RARRAY_PTR_USE(arg, ptr, {
|
for (i=0; i<RARRAY_LEN(arg); i++) {
|
||||||
for(; len > 0; len--, ptr++) {
|
set_table_insert_wb(into, set, RARRAY_AREF(arg, i), NULL);
|
||||||
set_table_insert_wb(into, set, *ptr, NULL);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -632,6 +632,17 @@ class TC_Set < Test::Unit::TestCase
|
|||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_merge_mutating_hash_bug_21305
|
||||||
|
a = (1..100).to_a
|
||||||
|
o = Object.new
|
||||||
|
o.define_singleton_method(:hash) do
|
||||||
|
a.clear
|
||||||
|
0
|
||||||
|
end
|
||||||
|
a.unshift o
|
||||||
|
assert_equal([o], Set.new.merge(a).to_a)
|
||||||
|
end
|
||||||
|
|
||||||
def test_subtract
|
def test_subtract
|
||||||
set = Set[1,2,3]
|
set = Set[1,2,3]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user