Project

General

Profile

Bug #16676

`#hash` can change Hash object from ar_table to st_table

Added by ko1 (Koichi Sasada) 4 months ago. Updated 3 months ago.

Status:
Closed
Priority:
Normal
Target version:
[ruby-core:97383]

Description

Points

  • Hash representation ar_table has a problem from Ruby 2.6 (need to backport)

Problem

From Ruby 2.6 Hash object is represented by ar_table (for small (<=8) pairs) and st_table.
To lookup hash table, Object#hash is called to get a hash value, and this method call can modify Hash object.
It means that the code assumes the Hash representation is a ar_table, but calling the #hash method, it can be a st_table.

I believe nobody modify Hash table from #hash method (it should be pure, no-side effect method), but multi-threads can modify a Hash object, it can be exposed.

I will commit a patch soon.

Workaround

To avoid this issue, making a hash table in st_table, for example:

h = {} # ar_table
10.times{|i| h[i] = i} # st_table because the number of pair == 10 (> 8)
h.clear

Files

bugs_16676_patch_for_2_6.patch (3.37 KB) bugs_16676_patch_for_2_6.patch nagachika (Tomoyuki Chikanaga), 03/27/2020 02:24 AM

Updated by ko1 (Koichi Sasada) 4 months ago

  • Status changed from Open to Closed

4c019f5a626523e99e2827ed917802e3097c380d
c3584dfacce4d0f2058d8403de6fdce4fd4d686b

#2

Updated by ko1 (Koichi Sasada) 4 months ago

  • Backport changed from 2.5: UNKNOWN, 2.6: UNKNOWN, 2.7: UNKNOWN to 2.5: UNKNOWN, 2.6: REQUIRED, 2.7: REQUIRED

Updated by naruse (Yui NARUSE) 4 months ago

  • Backport changed from 2.5: UNKNOWN, 2.6: REQUIRED, 2.7: REQUIRED to 2.5: UNKNOWN, 2.6: REQUIRED, 2.7: DONE

ruby_2_7 ab6f78bc926f6fc12dc8d7846056fc9c04d63ead.

Updated by nagachika (Tomoyuki Chikanaga) 3 months ago

I created the patch for ruby_2_6 branch (attatched file).

But the test_ar2st failed.

  1) Failure:
TestHash#test_ar2st [/Users/nagachika/opt/ruby-2.6/src/ruby_2_6/test/ruby/test_hash.rb:1749]:
<"{0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, test=>true}"> expected but was
<"{0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9}">.

  2) Failure:
TestHash::TestSubHash#test_ar2st [/Users/nagachika/opt/ruby-2.6/src/ruby_2_6/test/ruby/test_hash.rb:1749]:
<"{0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, test=>true}"> expected but was
<"{0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9}">.

Updated by nagachika (Tomoyuki Chikanaga) 3 months ago

  • Backport changed from 2.5: UNKNOWN, 2.6: REQUIRED, 2.7: DONE to 2.5: UNKNOWN, 2.6: DONE, 2.7: DONE

ruby_2_6 r67858 merged revision(s) 4c019f5a626523e99e2827ed917802e3097c380d,c3584dfacce4d0f2058d8403de6fdce4fd4d686b.

#6

Updated by nobu (Nobuyoshi Nakada) 3 months ago

  • Backport changed from 2.5: UNKNOWN, 2.6: DONE, 2.7: DONE to 2.5: DONTNEED, 2.6: DONE, 2.7: DONE

Also available in: Atom PDF