summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--hash.c8
-rw-r--r--test/ruby/test_hash.rb9
3 files changed, 19 insertions, 3 deletions
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 <nobu@ruby-lang.org>
+
+ * hash.c (hash_i): return different values for inverse hash.
+ [ruby-core:34334]
+
Tue Jan 11 20:32:59 2011 Tanaka Akira <akr@fsij.org>
* 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