Skip to content
  • John Hawthorn's avatar
    698741d7
    Replace tombstone when converting AR to ST hash · 698741d7
    John Hawthorn authored
    
    
    [Bug #21170]
    
    st_table reserves -1 as a special hash value to indicate that an entry
    has been deleted. So that that's a valid value to be returned from the
    hash function, do_hash replaces -1 with 0 so that it is not mistaken for
    the sentinel.
    
    Previously, when upgrading an AR table to an ST table,
    rb_st_add_direct_with_hash was used which did not perform the same
    conversion, this could lead to a hash in a broken state where one if its
    entries which was supposed to exist being marked as a tombstone.
    
    The hash could then become further corrupted when the ST table required
    resizing as the falsely tombstoned entry would be skipped but it would
    be counted in num entries, leading to an uninitialized entry at index
    15.
    
    In most cases this will be really rare, unless using a very poorly
    implemented custom hash function.
    
    This also adds two debug assertions, one that st_add_direct_with_hash
    does not receive the reserved hash value, and a second in
    rebuild_table_with, which ensures that after we rebuild/compact a table
    it contains the expected number of elements.
    
    Co-authored-by: default avatarAlan Wu <alanwu@ruby-lang.org>
    698741d7
    Replace tombstone when converting AR to ST hash
    John Hawthorn authored
    
    
    [Bug #21170]
    
    st_table reserves -1 as a special hash value to indicate that an entry
    has been deleted. So that that's a valid value to be returned from the
    hash function, do_hash replaces -1 with 0 so that it is not mistaken for
    the sentinel.
    
    Previously, when upgrading an AR table to an ST table,
    rb_st_add_direct_with_hash was used which did not perform the same
    conversion, this could lead to a hash in a broken state where one if its
    entries which was supposed to exist being marked as a tombstone.
    
    The hash could then become further corrupted when the ST table required
    resizing as the falsely tombstoned entry would be skipped but it would
    be counted in num entries, leading to an uninitialized entry at index
    15.
    
    In most cases this will be really rare, unless using a very poorly
    implemented custom hash function.
    
    This also adds two debug assertions, one that st_add_direct_with_hash
    does not receive the reserved hash value, and a second in
    rebuild_table_with, which ensures that after we rebuild/compact a table
    it contains the expected number of elements.
    
    Co-authored-by: default avatarAlan Wu <alanwu@ruby-lang.org>
Loading