From 79afabe0c5f5aa1df305fac7708f1d5ef278bc83 Mon Sep 17 00:00:00 2001 From: mame Date: Tue, 16 Feb 2010 16:20:18 +0000 Subject: * 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 --- hash.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'hash.c') diff --git a/hash.c b/hash.c index d49d0ea71d..51537e91b6 100644 --- a/hash.c +++ b/hash.c @@ -269,6 +269,14 @@ rb_hash_modify(VALUE hash) rb_hash_tbl(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) { @@ -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; } -- cgit v1.2.3