diff options
author | Jean Boussier <[email protected]> | 2023-04-11 10:55:46 +0200 |
---|---|---|
committer | Jean Boussier <[email protected]> | 2023-04-11 16:56:14 +0200 |
commit | 8c360ce713f57d4177de833297364f6f6d950420 (patch) | |
tree | df98faaf72d599ca733fec57198c66047f62c45f /hash.c | |
parent | 7b230bc8486e7d451113c3c0301adcecfc09b893 (diff) |
hash.c: Fix hash_iter_lev_dec corrupting shape
[Bug #19589]
When decrementing `iter_lev` from `65` to `64` the flags would be
corrupted, causing the shape_id to be invalid.
Notes
Notes:
Merged: https://github.com/ruby/ruby/pull/7686
Diffstat (limited to 'hash.c')
-rw-r--r-- | hash.c | 12 |
1 files changed, 9 insertions, 3 deletions
@@ -1367,13 +1367,19 @@ iter_lev_in_ivar_set(VALUE hash, int lev) rb_ivar_set_internal(hash, id_hash_iter_lev, INT2FIX(lev)); } -static int +static inline int iter_lev_in_flags(VALUE hash) { unsigned int u = (unsigned int)((RBASIC(hash)->flags >> RHASH_LEV_SHIFT) & RHASH_LEV_MAX); return (int)u; } +static inline void +iter_lev_in_flags_set(VALUE hash, int lev) +{ + RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | ((VALUE)lev << RHASH_LEV_SHIFT)); +} + static int RHASH_ITER_LEV(VALUE hash) { @@ -1397,7 +1403,7 @@ hash_iter_lev_inc(VALUE hash) } else { lev += 1; - RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | ((VALUE)lev << RHASH_LEV_SHIFT)); + iter_lev_in_flags_set(hash, lev); if (lev == RHASH_LEV_MAX) { iter_lev_in_ivar_set(hash, lev); } @@ -1415,7 +1421,7 @@ hash_iter_lev_dec(VALUE hash) } else { HASH_ASSERT(lev > 0); - RBASIC(hash)->flags = ((RBASIC(hash)->flags & ~RHASH_LEV_MASK) | ((lev-1) << RHASH_LEV_SHIFT)); + iter_lev_in_flags_set(hash, lev - 1); } } |