зеркало из 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
|
static int
|
||||||
ar_general_foreach(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg)
|
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);
|
ar_table_pair *pair = RHASH_AR_TABLE_REF(hash, i);
|
||||||
enum st_retval retval = (*func)(pair->key, pair->val, arg, 0);
|
enum st_retval retval = (*func)(pair->key, pair->val, arg, 0);
|
||||||
|
ensure_ar_table(hash);
|
||||||
/* pair may be not valid here because of theap */
|
/* pair may be not valid here because of theap */
|
||||||
|
|
||||||
switch (retval) {
|
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);
|
hint = ar_hint(hash, i);
|
||||||
|
|
||||||
retval = (*func)(key, pair->val, arg, 0);
|
retval = (*func)(key, pair->val, arg, 0);
|
||||||
|
ensure_ar_table(hash);
|
||||||
hash_verify(hash);
|
hash_verify(hash);
|
||||||
|
|
||||||
switch (retval) {
|
switch (retval) {
|
||||||
|
@ -956,6 +966,7 @@ ar_update(VALUE hash, st_data_t key,
|
||||||
old_key = key;
|
old_key = key;
|
||||||
retval = (*func)(&key, &value, arg, existing);
|
retval = (*func)(&key, &value, arg, existing);
|
||||||
/* pair can be invalid here because of theap */
|
/* pair can be invalid here because of theap */
|
||||||
|
ensure_ar_table(hash);
|
||||||
|
|
||||||
switch (retval) {
|
switch (retval) {
|
||||||
case ST_CONTINUE:
|
case ST_CONTINUE:
|
||||||
|
|
Загрузка…
Ссылка в новой задаче