merge revision(s) 7793b59c8d2a13c124fe276e11723db23facce04: [Backport #21331]
[Bug #21331] Prohibit hash modification during stlike loop
This commit is contained in:
parent
b25bfd33e9
commit
cb49400d68
20
hash.c
20
hash.c
@ -1391,6 +1391,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)
|
||||
{
|
||||
@ -1402,6 +1403,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)
|
||||
{
|
||||
@ -3326,6 +3328,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:
|
||||
* hash.transform_values {|value| ... } -> new_hash
|
||||
@ -3356,7 +3372,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);
|
||||
}
|
||||
|
||||
@ -3385,7 +3401,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;
|
||||
|
@ -1816,6 +1816,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
|
||||
|
@ -11,7 +11,7 @@
|
||||
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
|
||||
#define RUBY_VERSION_TEENY 8
|
||||
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
|
||||
#define RUBY_PATCHLEVEL 148
|
||||
#define RUBY_PATCHLEVEL 149
|
||||
|
||||
#include "ruby/version.h"
|
||||
#include "ruby/internal/abi.h"
|
||||
|
Loading…
x
Reference in New Issue
Block a user