зеркало из https://github.com/github/ruby.git
Raise an exception if ar_table is converted to st_table during iteration
ar_table may be converted to st_table by `ar_force_convert_table`. If the conversion occurs during the iteration of ar_table, the iteration may lead to memory corruption. This change prevents the catastrophy by throwing an exception when the conversion is detected. This issue is reported by [SuperS](https://hackerone.com/superss)
This commit is contained in:
Родитель
c3ab946e86
Коммит
a787e0d649
11
hash.c
11
hash.c
|
@ -811,6 +811,14 @@ ar_add_direct_with_hash(VALUE hash, st_data_t key, st_data_t val, st_hash_t hash
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_ar_table(VALUE hash)
|
||||
{
|
||||
if (!RHASH_AR_TABLE_P(hash)) {
|
||||
rb_raise(rb_eRuntimeError, "hash representation was changed during iteration");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
ar_general_foreach(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
|
||||
{
|
||||
|
@ -822,6 +830,7 @@ ar_general_foreach(VALUE hash, st_foreach_check_callback_func *func, st_update_c
|
|||
|
||||
ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
|
||||
enum st_retval retval = (*func)(pair->key, pair->val, arg, 0);
|
||||
ensure_ar_table(hash);
|
||||
/* pair may be not valid here because of theap */
|
||||
|
||||
switch (retval) {
|
||||
|
@ -896,6 +905,7 @@ ar_foreach_check(VALUE hash, st_foreach_check_callback_func *func, st_data_t arg
|
|||
hint = ar_hint(hash, i);
|
||||
|
||||
retval = (*func)(key, pair->val, arg, 0);
|
||||
ensure_ar_table(hash);
|
||||
hash_verify(hash);
|
||||
|
||||
switch (retval) {
|
||||
|
@ -956,6 +966,7 @@ ar_update(VALUE hash, st_data_t key,
|
|||
old_key = key;
|
||||
retval = (*func)(&key, &value, arg, existing);
|
||||
/* pair can be invalid here because of theap */
|
||||
ensure_ar_table(hash);
|
||||
|
||||
switch (retval) {
|
||||
case ST_CONTINUE:
|
||||
|
|
Загрузка…
Ссылка в новой задаче