[Bug #21331] Prohibit hash modification during stlike loop
This commit is contained in:
parent
7f5b4fb26e
commit
7793b59c8d
Notes:
git
2025-05-14 02:42:50 +00:00
20
hash.c
20
hash.c
@ -1404,6 +1404,7 @@ hash_foreach_ensure(VALUE hash)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This does not manage iteration level */
|
||||
int
|
||||
rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg)
|
||||
{
|
||||
@ -1415,6 +1416,7 @@ rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg
|
||||
}
|
||||
}
|
||||
|
||||
/* This does not manage iteration level */
|
||||
int
|
||||
rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
|
||||
{
|
||||
@ -3486,6 +3488,20 @@ transform_values_foreach_replace(st_data_t *key, st_data_t *value, st_data_t arg
|
||||
return ST_CONTINUE;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
transform_values_call(VALUE hash)
|
||||
{
|
||||
rb_hash_stlike_foreach_with_replace(hash, transform_values_foreach_func, transform_values_foreach_replace, hash);
|
||||
return hash;
|
||||
}
|
||||
|
||||
static void
|
||||
transform_values(VALUE hash)
|
||||
{
|
||||
hash_iter_lev_inc(hash);
|
||||
rb_ensure(transform_values_call, hash, hash_foreach_ensure, hash);
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* transform_values {|value| ... } -> new_hash
|
||||
@ -3514,7 +3530,7 @@ rb_hash_transform_values(VALUE hash)
|
||||
SET_DEFAULT(result, Qnil);
|
||||
|
||||
if (!RHASH_EMPTY_P(hash)) {
|
||||
rb_hash_stlike_foreach_with_replace(result, transform_values_foreach_func, transform_values_foreach_replace, result);
|
||||
transform_values(result);
|
||||
compact_after_delete(result);
|
||||
}
|
||||
|
||||
@ -3549,7 +3565,7 @@ rb_hash_transform_values_bang(VALUE hash)
|
||||
rb_hash_modify_check(hash);
|
||||
|
||||
if (!RHASH_TABLE_EMPTY_P(hash)) {
|
||||
rb_hash_stlike_foreach_with_replace(hash, transform_values_foreach_func, transform_values_foreach_replace, hash);
|
||||
transform_values(hash);
|
||||
}
|
||||
|
||||
return hash;
|
||||
|
@ -1853,6 +1853,14 @@ class TestHash < Test::Unit::TestCase
|
||||
end
|
||||
end
|
||||
assert_equal(@cls[a: 2, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10], x)
|
||||
|
||||
x = (1..1337).to_h {|k| [k, k]}
|
||||
assert_raise_with_message(RuntimeError, /rehash during iteration/) do
|
||||
x.transform_values! {|v|
|
||||
x.rehash if v == 1337
|
||||
v * 2
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def hrec h, n, &b
|
||||
|
Loading…
x
Reference in New Issue
Block a user