summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--set.c12
-rw-r--r--test/ruby/test_set.rb11
2 files changed, 15 insertions, 8 deletions
diff --git a/set.c b/set.c
index 221b9a07e1..0f72a8ea4d 100644
--- a/set.c
+++ b/set.c
@@ -1120,14 +1120,10 @@ set_merge_enum_into(VALUE set, VALUE arg)
set_iter(arg, set_merge_i, (st_data_t)&args);
}
else if (RB_TYPE_P(arg, T_ARRAY)) {
- long len = RARRAY_LEN(arg);
- if (RARRAY_LEN(arg) != 0) {
- set_table *into = RSET_TABLE(set);
- RARRAY_PTR_USE(arg, ptr, {
- for(; len > 0; len--, ptr++) {
- set_table_insert_wb(into, set, *ptr, NULL);
- }
- });
+ long i;
+ set_table *into = RSET_TABLE(set);
+ for (i=0; i<RARRAY_LEN(arg); i++) {
+ set_table_insert_wb(into, set, RARRAY_AREF(arg, i), NULL);
}
}
else {
diff --git a/test/ruby/test_set.rb b/test/ruby/test_set.rb
index 2de6cdaaee..225b7da78c 100644
--- a/test/ruby/test_set.rb
+++ b/test/ruby/test_set.rb
@@ -632,6 +632,17 @@ class TC_Set < Test::Unit::TestCase
}
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
set = Set[1,2,3]