diff --git a/string.c b/string.c index c38473481fb1a6..e46af72def0f9d 100644 --- a/string.c +++ b/string.c @@ -3586,11 +3586,12 @@ rb_str_prepend_multi(int argc, VALUE *argv, VALUE str) st_index_t rb_str_hash(VALUE str) { + st_index_t h = rb_memhash((const void *)RSTRING_PTR(str), RSTRING_LEN(str)); int e = RSTRING_LEN(str) ? ENCODING_GET(str) : 0; - if (e && is_ascii_string(str)) { - e = 0; + if (e && !is_ascii_string(str)) { + h = rb_hash_end(rb_hash_uint32(h, (uint32_t)e)); } - return rb_memhash((const void *)RSTRING_PTR(str), RSTRING_LEN(str)) ^ e; + return h; } int diff --git a/test/ruby/test_string.rb b/test/ruby/test_string.rb index 4d5dea73283c8f..ae392b2da60295 100644 --- a/test/ruby/test_string.rb +++ b/test/ruby/test_string.rb @@ -1345,6 +1345,8 @@ def test_hash bug9172 = '[ruby-core:58658] [Bug #9172]' assert_not_equal(S("sub-setter").hash, S("discover").hash, bug9172) assert_equal(S("").hash, S("".encode(Encoding::UTF_32BE)).hash) + h1, h2 = ["\x80", "\x81"].map {|c| c.b.hash ^ c.hash} + assert_not_equal(h1, h2) end def test_hex