ruby-changes:14824
From: mame <ko1@a...>
Date: Wed, 17 Feb 2010 01:20:38 +0900 (JST)
Subject: [ruby-changes:14824] Ruby:r26687 (trunk): * hash.c (hash_update): always raise an exception when adding a new
mame 2010-02-17 01:20:18 +0900 (Wed, 17 Feb 2010) New Revision: 26687 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=26687 Log: * 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] Modified files: trunk/ChangeLog trunk/hash.c Index: ChangeLog =================================================================== --- ChangeLog (revision 26686) +++ ChangeLog (revision 26687) @@ -1,3 +1,10 @@ +Wed Feb 17 01:16:12 2010 Yusuke Endoh <mame@t...> + + * 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] + Tue Feb 16 22:09:27 2010 Yusuke Endoh <mame@t...> * gc.c (chain_finalized_object): fix precedence. Index: hash.c =================================================================== --- hash.c (revision 26686) +++ hash.c (revision 26687) @@ -270,6 +270,14 @@ } 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 @@ 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 @@ 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 @@ 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; } -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/