зеркало из https://github.com/github/ruby.git
merge revision(s) 8c360ce713f57d4177de833297364f6f6d950420: [Backport #19589]
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. --- hash.c | 12 +++++++++--- test/ruby/test_hash.rb | 11 +++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-)
This commit is contained in:
Родитель
a7b0d3c9db
Коммит
8165db0f46
12
hash.c
12
hash.c
|
@ -1409,13 +1409,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)
|
||||
{
|
||||
|
@ -1439,7 +1445,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);
|
||||
}
|
||||
|
@ -1457,7 +1463,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1556,6 +1556,17 @@ class TestHash < Test::Unit::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def hash_iter_recursion(h, level)
|
||||
return if level == 0
|
||||
h.each_key {}
|
||||
h.each_value { hash_iter_recursion(h, level - 1) }
|
||||
end
|
||||
|
||||
def test_iterlevel_in_ivar_bug19589
|
||||
h = { a: nil }
|
||||
hash_iter_recursion(h, 200)
|
||||
end
|
||||
|
||||
def test_threaded_iter_level
|
||||
bug9105 = '[ruby-dev:47807] [Bug #9105]'
|
||||
h = @cls[1=>2]
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
|
||||
#define RUBY_VERSION_TEENY 2
|
||||
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
|
||||
#define RUBY_PATCHLEVEL 86
|
||||
#define RUBY_PATCHLEVEL 87
|
||||
|
||||
#include "ruby/version.h"
|
||||
#include "ruby/internal/abi.h"
|
||||
|
|
Загрузка…
Ссылка в новой задаче