Fixed crash in ZEND_ASSIGN_DIM_OP because of array cloberring by user error handler

Fixes oss-fuzz #36214
This commit is contained in:
Dmitry Stogov 2021-11-30 23:33:34 +03:00
parent 2fb7b6e3e9
commit b594a95a2f
2 changed files with 80 additions and 2 deletions

View file

@ -2214,10 +2214,37 @@ static zend_never_inline zend_uchar slow_index_convert(HashTable *ht, const zval
value->str = ZSTR_EMPTY_ALLOC();
return IS_STRING;
case IS_DOUBLE:
value->lval = zend_dval_to_lval_safe(Z_DVAL_P(dim));
value->lval = zend_dval_to_lval(Z_DVAL_P(dim));
if (!zend_is_long_compatible(Z_DVAL_P(dim), value->lval)) {
/* The array may be destroyed while throwing the notice.
* Temporarily increase the refcount to detect this situation. */
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
GC_ADDREF(ht);
}
zend_incompatible_double_to_long_error(Z_DVAL_P(dim));
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
zend_array_destroy(ht);
return IS_NULL;
}
if (EG(exception)) {
return IS_NULL;
}
}
return IS_LONG;
case IS_RESOURCE:
/* The array may be destroyed while throwing the notice.
* Temporarily increase the refcount to detect this situation. */
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE)) {
GC_ADDREF(ht);
}
zend_use_resource_as_offset(dim);
if (!(GC_FLAGS(ht) & IS_ARRAY_IMMUTABLE) && !GC_DELREF(ht)) {
zend_array_destroy(ht);
return IS_NULL;
}
if (EG(exception)) {
return IS_NULL;
}
value->lval = Z_RES_HANDLE_P(dim);
return IS_LONG;
case IS_FALSE: