mirror of
https://github.com/ruby/ruby.git
synced 2025-09-15 08:33:58 +02:00
* hash.c (rb_hash_rehash): add iteration check. [ruby-dev:24301]
* st.c (st_foreach): add deep check. * array.c (rb_ary_collect_bang): element size might change during comparison. [ruby-dev:24300] * array.c (rb_ary_reject_bang): ditto. [ruby-dev:24300] * array.c (rb_ary_eql): ditto. [ruby-dev:24300] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@6949 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
94fe903463
commit
9dcc08646f
5 changed files with 61 additions and 17 deletions
33
hash.c
33
hash.c
|
@ -121,24 +121,33 @@ struct rb_hash_foreach_arg {
|
|||
};
|
||||
|
||||
static int
|
||||
rb_hash_foreach_iter(key, value, arg)
|
||||
rb_hash_foreach_iter(key, value, arg, err)
|
||||
VALUE key, value;
|
||||
struct rb_hash_foreach_arg *arg;
|
||||
int err;
|
||||
{
|
||||
int status;
|
||||
st_table *tbl = RHASH(arg->hash)->tbl;
|
||||
struct st_table_entry **bins = tbl->bins;
|
||||
st_table *tbl;
|
||||
|
||||
if (err) {
|
||||
rb_raise(rb_eRuntimeError, "hash modified during iteration");
|
||||
}
|
||||
tbl = RHASH(arg->hash)->tbl;
|
||||
if (key == Qundef) return ST_CONTINUE;
|
||||
status = (*arg->func)(key, value, arg->arg);
|
||||
if (RHASH(arg->hash)->tbl != tbl ||
|
||||
RHASH(arg->hash)->tbl->bins != bins) {
|
||||
rb_raise(rb_eIndexError, "rehash occurred during iteration");
|
||||
if (RHASH(arg->hash)->tbl != tbl) {
|
||||
rb_raise(rb_eRuntimeError, "rehash occurred during iteration");
|
||||
}
|
||||
if (RHASH(arg->hash)->iter_lev == 0) {
|
||||
rb_raise(rb_eArgError, "block re-entered");
|
||||
switch (status) {
|
||||
case ST_DELETE:
|
||||
st_delete_safe(tbl, (st_data_t*)&key, 0, Qundef);
|
||||
FL_SET(arg->hash, HASH_DELETED);
|
||||
case ST_CONTINUE:
|
||||
break;
|
||||
case ST_STOP:
|
||||
return ST_STOP;
|
||||
}
|
||||
return status;
|
||||
return ST_CHECK;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
|
@ -836,8 +845,12 @@ static VALUE
|
|||
rb_hash_clear(hash)
|
||||
VALUE hash;
|
||||
{
|
||||
void *tmp;
|
||||
|
||||
rb_hash_modify(hash);
|
||||
st_foreach(RHASH(hash)->tbl, clear_i, 0);
|
||||
if (RHASH(hash)->tbl->num_entries > 0) {
|
||||
st_foreach(RHASH(hash)->tbl, clear_i, 0);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue