1
0
mirror of https://github.com/php/php-src.git synced 2026-04-20 06:21:12 +02:00

Merge branch 'PHP-8.0' into PHP-8.1

* PHP-8.0:
  Fix array clobering by user error handler
This commit is contained in:
Dmitry Stogov
2021-12-13 15:20:16 +03:00
6 changed files with 318 additions and 476 deletions

View File

@@ -904,13 +904,15 @@ try_string_offset:
static void ZEND_FASTCALL zend_jit_fetch_dim_obj_r_helper(zval *container, zval *dim, zval *result)
{
zval *retval;
zend_object *obj = Z_OBJ_P(container);
GC_ADDREF(obj);
if (UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {
zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var);
dim = &EG(uninitialized_zval);
}
retval = Z_OBJ_HT_P(container)->read_dimension(Z_OBJ_P(container), dim, BP_VAR_R, result);
retval = obj->handlers->read_dimension(obj, dim, BP_VAR_R, result);
if (retval) {
if (result != retval) {
@@ -921,18 +923,23 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_obj_r_helper(zval *container, zval
} else {
ZVAL_NULL(result);
}
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
zend_objects_store_del(obj);
}
}
static void ZEND_FASTCALL zend_jit_fetch_dim_obj_is_helper(zval *container, zval *dim, zval *result)
{
zval *retval;
zend_object *obj = Z_OBJ_P(container);
GC_ADDREF(obj);
if (UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {
zend_jit_undefined_op_helper(EG(current_execute_data)->opline->op2.var);
dim = &EG(uninitialized_zval);
}
retval = Z_OBJ_HT_P(container)->read_dimension(Z_OBJ_P(container), dim, BP_VAR_IS, result);
retval = obj->handlers->read_dimension(obj, dim, BP_VAR_IS, result);
if (retval) {
if (result != retval) {
@@ -943,6 +950,9 @@ static void ZEND_FASTCALL zend_jit_fetch_dim_obj_is_helper(zval *container, zval
} else {
ZVAL_NULL(result);
}
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
zend_objects_store_del(obj);
}
}
static zend_never_inline void zend_assign_to_string_offset(zval *str, zval *dim, zval *value, zval *result)
@@ -1103,16 +1113,11 @@ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper(zval
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_object *obj = Z_OBJ_P(object_ptr);
GC_ADDREF(obj);
if (dim && UNEXPECTED(Z_ISUNDEF_P(dim))) {
const zend_op *opline = EG(current_execute_data)->opline;
GC_ADDREF(obj);
zend_jit_undefined_op_helper(opline->op2.var);
dim = &EG(uninitialized_zval);
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
zend_objects_store_del(obj);
ZVAL_NULL(result);
return;
}
}
retval = obj->handlers->read_dimension(obj, dim, type, result);
@@ -1141,6 +1146,9 @@ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper(zval
ZEND_ASSERT(EG(exception) && "read_dimension() returned NULL without exception");
ZVAL_UNDEF(result);
}
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
zend_objects_store_del(obj);
}
} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING)) {
if (!dim) {
zend_throw_error(NULL, "[] operator not supported for strings");
@@ -1208,38 +1216,23 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim
if (EXPECTED(Z_TYPE_P(object_ptr) == IS_OBJECT)) {
zend_object *obj = Z_OBJ_P(object_ptr);
GC_ADDREF(obj);
if (dim && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {
const zend_op *opline = EG(current_execute_data)->opline;
GC_ADDREF(obj);
zend_jit_undefined_op_helper(opline->op2.var);
dim = &EG(uninitialized_zval);
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
zend_objects_store_del(obj);
if (result) {
ZVAL_NULL(result);
}
return;
}
}
if (UNEXPECTED(Z_TYPE_P(value) == IS_UNDEF)) {
const zend_op *op_data = EG(current_execute_data)->opline + 1;
ZEND_ASSERT(op_data->opcode == ZEND_OP_DATA && op_data->op1_type == IS_CV);
GC_ADDREF(obj);
zend_jit_undefined_op_helper(op_data->op1.var);
value = &EG(uninitialized_zval);
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
zend_objects_store_del(obj);
if (result) {
ZVAL_NULL(result);
}
return;
}
} else {
ZVAL_DEREF(value);
}
Z_OBJ_HT_P(object_ptr)->write_dimension(obj, dim, value);
obj->handlers->write_dimension(obj, dim, value);
if (result) {
if (EXPECTED(!EG(exception))) {
ZVAL_COPY(result, value);
@@ -1247,6 +1240,9 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim
ZVAL_UNDEF(result);
}
}
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
zend_objects_store_del(obj);
}
return;
} else if (EXPECTED(Z_TYPE_P(object_ptr) == IS_STRING) && EXPECTED(dim != NULL)) {
zend_assign_to_string_offset(object_ptr, dim, value, result);
@@ -1311,18 +1307,11 @@ static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *d
zval *z;
zval rv, res;
GC_ADDREF(obj);
if (dim && UNEXPECTED(Z_ISUNDEF_P(dim))) {
const zend_op *opline = EG(current_execute_data)->opline;
GC_ADDREF(obj);
zend_jit_undefined_op_helper(opline->op2.var);
dim = &EG(uninitialized_zval);
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
zend_objects_store_del(obj);
//??? if (retval) {
//??? ZVAL_NULL(retval);
//??? }
return;
}
}
z = obj->handlers->read_dimension(obj, dim, BP_VAR_R, &rv);
@@ -1338,6 +1327,12 @@ static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *d
} else {
zend_error(E_WARNING, "Attempt to assign property of non-object");
}
if (UNEXPECTED(GC_DELREF(obj) == 0)) {
zend_objects_store_del(obj);
//??? if (retval) {
//??? ZVAL_NULL(retval);
//??? }
}
} else if (UNEXPECTED(Z_TYPE_P(container) == IS_STRING)) {
if (!dim) {
zend_throw_error(NULL, "[] operator not supported for strings");