summaryrefslogtreecommitdiff
path: root/hash.c
diff options
context:
space:
mode:
authormame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-02-16 16:20:18 +0000
committermame <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2010-02-16 16:20:18 +0000
commit79afabe0c5f5aa1df305fac7708f1d5ef278bc83 (patch)
treecd202280556006e3326b3b1f3f18b11eb6e1c727 /hash.c
parent4651910af145c2b52c100385fbc7245f01846f72 (diff)
* hash.c (hash_update): always raise an exception when adding a new
key during iteration. Traditionally, an exception was raised only when rehash occurs, but it may lead to difficult bug to reproduce. [ruby-core:23614] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@26687 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'hash.c')
-rw-r--r--hash.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/hash.c b/hash.c
index d49d0ea71d..51537e91b6 100644
--- a/hash.c
+++ b/hash.c
@@ -270,6 +270,14 @@ rb_hash_modify(VALUE hash)
}
static void
+hash_update(VALUE hash, VALUE key)
+{
+ if (RHASH(hash)->iter_lev > 0 && !st_lookup(RHASH(hash)->ntbl, key, 0)) {
+ rb_raise(rb_eRuntimeError, "can't add a new key into hash during iteration");
+ }
+}
+
+static void
default_proc_arity_check(VALUE proc)
{
int n = rb_proc_arity(proc);
@@ -1036,6 +1044,7 @@ VALUE
rb_hash_aset(VALUE hash, VALUE key, VALUE val)
{
rb_hash_modify(hash);
+ hash_update(hash, key);
if (hash == key) {
rb_raise(rb_eArgError, "recursive key for hash");
}
@@ -1630,6 +1639,7 @@ static int
rb_hash_update_i(VALUE key, VALUE value, VALUE hash)
{
if (key == Qundef) return ST_CONTINUE;
+ hash_update(hash, key);
st_insert(RHASH(hash)->ntbl, key, value);
return ST_CONTINUE;
}
@@ -1641,6 +1651,7 @@ rb_hash_update_block_i(VALUE key, VALUE value, VALUE hash)
if (rb_hash_has_key(hash, key)) {
value = rb_yield_values(3, key, rb_hash_aref(hash, key), value);
}
+ hash_update(hash, key);
st_insert(RHASH(hash)->ntbl, key, value);
return ST_CONTINUE;
}