diff --git a/ChangeLog b/ChangeLog index d8dcd356d5..4db8d1cc13 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Wed Jan 12 08:37:07 2011 Nobuyoshi Nakada + + * hash.c (hash_i): return different values for inverse hash. + [ruby-core:34334] + Tue Jan 11 20:32:59 2011 Tanaka Akira * variable.c: parenthesize macro arguments. diff --git a/hash.c b/hash.c index c769e60986..c7ac394bcb 100644 --- a/hash.c +++ b/hash.c @@ -1663,9 +1663,12 @@ static int hash_i(VALUE key, VALUE val, VALUE arg) { st_index_t *hval = (st_index_t *)arg; + st_index_t hdata[2]; if (key == Qundef) return ST_CONTINUE; - *hval ^= rb_hash_end(rb_hash_uint(rb_hash_start(rb_hash(key)), rb_hash(val))); + hdata[0] = rb_hash(key); + hdata[1] = rb_hash(val); + *hval ^= st_hash(hdata, sizeof(hdata), 0); return ST_CONTINUE; } @@ -1678,9 +1681,10 @@ recursive_hash(VALUE hash, VALUE dummy, int recur) return LONG2FIX(0); hval = RHASH(hash)->ntbl->num_entries; if (recur) - hval = rb_hash_end(rb_hash_uint(rb_hash_start(rb_hash(rb_cHash)), hval)); + hval = rb_hash_uint(rb_hash_start(rb_hash(rb_cHash)), hval); else rb_hash_foreach(hash, hash_i, (VALUE)&hval); + hval = rb_hash_end(hval); return INT2FIX(hval); } diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb index 782edc9a0c..4c0d556896 100644 --- a/test/ruby/test_hash.rb +++ b/test/ruby/test_hash.rb @@ -890,7 +890,7 @@ class TestHash < Test::Unit::TestCase assert_equal({x=>1}.hash, {x=>1}.hash) o = Object.new - def o.hash; 2<<100; end + def o.hash; 2 << 100; end assert_equal({x=>1}.hash, {x=>1}.hash) end @@ -904,4 +904,11 @@ class TestHash < Test::Unit::TestCase h.rehash assert_equal(:foo, h[h]) end + + def test_inverse_hash + feature4262 = '[ruby-core:34334]' + [{1=>2}, {123=>"abc"}].each do |h| + assert_not_equal(h.hash, h.invert.hash, feature4262) + end + end end