8000 merge revision(s) bb180b87b43c45e17ff49735a26d7a188d5c8396: [Backport… · github/ruby@862480a · GitHub
[go: up one dir, main page]

Skip to content

Commit 862480a

Browse files
committed
merge revision(s) bb180b8: [Backport #21331]
[Bug #21331] Prohibit modification during stlike loop
1 parent 7e44df9 commit 862480a

File tree

3 files changed

+75
-9
lines changed

3 files changed

+75
-9
lines changed

hash.c

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -880,7 +880,7 @@ ar_general_foreach(VALUE hash, st_foreach_check_callback_func *func, st_update_c
880880
return 0;
881881
case ST_REPLACE:
882882
if (replace) {
883-
retval = (*replace)(&key, &val, arg, TRUE);
883+
(*replace)(&key, &val, arg, TRUE);
884884

885885
// TODO: pair should be same as pair before.
886886
pair = RHASH_AR_TABLE_REF(hash, i);
@@ -1404,26 +1404,84 @@ hash_foreach_ensure(VALUE hash)
14041404
return 0;
14051405
}
14061406

1407-
int
1408-
rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg)
1407+
struct hash_stlike_foreach_arg {
1408+
VALUE hash;
1409+
st_foreach_callback_func *func;
1410+
VALUE arg;
1411+
};
1412+
1413+
static VALUE
1414+
hash_stlike_foreach_call(VALUE args)
14091415
{
1416+
struct hash_stlike_foreach_arg *argp = (void *)args;
1417+
VALUE hash = argp->hash;
1418+
st_foreach_callback_func *func = argp->func;
1419+
VALUE arg = argp->arg;
1420+
int ret;
1421+
14101422
if (RHASH_AR_TABLE_P(hash)) {
1411-
return ar_foreach(hash, func, arg);
1423+
ret = ar_foreach(hash, func, arg);
14121424
}
14131425
else {
1414-
return st_foreach(RHASH_ST_TABLE(hash), func, arg);
1426+
ret = st_foreach(RHASH_ST_TABLE(hash), func, arg);
14151427
}
1428+
return (VALUE)ret;
14161429
}
14171430

14181431
int
1419-
rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
1432+
rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg)
14201433
{
1434+
struct hash_stlike_foreach_arg args = {
1435+
.hash = hash,
1436+
.func = func,
1437+
.arg = arg,
1438+
};
1439+
hash_iter_lev_inc(hash);
1440+
VALUE ret = rb_ensure(hash_stlike_foreach_call, (VALUE)&args,
1441+
hash_foreach_ensure, hash);
1442+
return (int)ret;
1443+
}
1444+
1445+
struct hash_stlike_foreach_with_replace_arg {
1446+
VALUE hash;
1447+
st_foreach_check_callback_func *func;
1448+
st_update_callback_func *replace;
1449+
VALUE arg;
1450+
};
1451+
1452+
static VALUE
1453+
hash_stlike_foreach_with_replace_call(VALUE args)
1454+
{
1455+
struct hash_stlike_foreach_with_replace_arg *argp = (void *)args;
1456+
VALUE hash = argp->hash;
1457+
st_foreach_check_callback_func *func = argp->func;
1458+
st_update_callback_func *replace = argp->replace;
1459+
VALUE arg = argp->arg;
1460+
int ret;
1461+
14211462
if (RHASH_AR_TABLE_P(hash)) {
1422-
return ar_foreach_with_replace(hash, func, replace, arg);
1463+
ret = ar_foreach_with_replace(hash, func, replace, arg);
14231464
}
14241465
else {
1425-
return st_foreach_with_replace(RHASH_ST_TABLE(hash), func, replace, arg);
1466+
ret = st_foreach_with_replace(RHASH_ST_TABLE(hash), func, replace, arg);
14261467
}
1468+
return (VALUE)ret;
1469+
}
1470+
1471+
int
1472+
rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func,
1473+
st_update_callback_func *replace, st_data_t arg)
1474+
{
1475+
struct hash_stlike_foreach_with_replace_arg args = {
1476+
.hash = hash,
1477+
.func = func,
1478+
.replace = replace,
1479+
.arg = arg,
1480+
};
1481+
hash_iter_lev_inc(hash);
1482+
VALUE ret = rb_ensure(hash_stlike_foreach_with_replace_call, (VALUE)&args,
1483+
hash_foreach_ensure, hash);
1484+
return (int)ret;
14271485
}
14281486

14291487
static VALUE

test/ruby/test_hash.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1853,6 +1853,14 @@ def test_transform_values_bang
18531853
end
18541854
end
18551855
assert_equal(@cls[a: 2, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10], x)
1856+
1857+
x = (1..1337).to_h {|k| [k, k]}
1858+
assert_raise_with_message(RuntimeError, /rehash during iteration/) do
1859+
x.transform_values! {|v|
1860+
x.rehash if v == 1337
1861+
v * 2
1862+
}
1863+
end
18561864
end
18571865

18581866
def hrec h, n, &b

version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
1212
#define RUBY_VERSION_TEENY 3
1313
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_ 5249 RELEASE_DAY_STR
14-
#define RUBY_PATCHLEVEL 32
14+
#define RUBY_PATCHLEVEL 33
1515

1616
#include "ruby/version.h"
1717
#include "ruby/internal/abi.h"

0 commit comments

Comments
 (0)
0