mirror of
https://github.com/php/php-src.git
synced 2026-04-06 15:43:13 +02:00
Merge branch 'PHP-8.1'
* PHP-8.1: Fix use after free because of data clobbering by user error handler
This commit is contained in:
15
Zend/tests/falsetoarray_002.phpt
Normal file
15
Zend/tests/falsetoarray_002.phpt
Normal file
@@ -0,0 +1,15 @@
|
||||
--TEST--
|
||||
Autovivification of false to array with data clobbering by error handler
|
||||
--FILE--
|
||||
<?php
|
||||
set_error_handler(function($code, $msg) {
|
||||
echo "Err: $msg\n";
|
||||
$GLOBALS['a']='';
|
||||
});
|
||||
$a=[!'a'];
|
||||
$a[0][$d]='b';
|
||||
var_dump($a);
|
||||
?>
|
||||
--EXPECT--
|
||||
Err: Automatic conversion of false to array is deprecated
|
||||
string(0) ""
|
||||
@@ -2434,13 +2434,24 @@ fetch_from_array:
|
||||
if (type != BP_VAR_W && UNEXPECTED(Z_TYPE_P(container) == IS_UNDEF)) {
|
||||
ZVAL_UNDEFINED_OP1();
|
||||
}
|
||||
if (Z_TYPE_P(container) == IS_FALSE) {
|
||||
zend_false_to_array_deprecated();
|
||||
}
|
||||
if (type != BP_VAR_UNSET) {
|
||||
array_init(container);
|
||||
HashTable *ht = zend_new_array(0);
|
||||
zend_uchar old_type = Z_TYPE_P(container);
|
||||
|
||||
ZVAL_ARR(container, ht);
|
||||
if (UNEXPECTED(old_type == IS_FALSE)) {
|
||||
GC_ADDREF(ht);
|
||||
zend_false_to_array_deprecated();
|
||||
if (UNEXPECTED(GC_DELREF(ht) == 0)) {
|
||||
zend_array_destroy(ht);
|
||||
goto return_null;
|
||||
}
|
||||
}
|
||||
goto fetch_from_array;
|
||||
} else {
|
||||
if (UNEXPECTED(Z_TYPE_P(container) == IS_FALSE)) {
|
||||
zend_false_to_array_deprecated();
|
||||
}
|
||||
return_null:
|
||||
/* for read-mode only */
|
||||
if (ZEND_CONST_COND(dim_type == IS_CV, dim != NULL) && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {
|
||||
|
||||
@@ -1217,13 +1217,23 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
|
||||
}
|
||||
zend_binary_assign_op_obj_dim(container, dim OPLINE_CC EXECUTE_DATA_CC);
|
||||
} else if (EXPECTED(Z_TYPE_P(container) <= IS_FALSE)) {
|
||||
HashTable *ht;
|
||||
zend_uchar old_type;
|
||||
|
||||
if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_INFO_P(container) == IS_UNDEF)) {
|
||||
ZVAL_UNDEFINED_OP1();
|
||||
}
|
||||
if (Z_TYPE_P(container) == IS_FALSE) {
|
||||
ht = zend_new_array(8);
|
||||
old_type = Z_TYPE_P(container);
|
||||
ZVAL_ARR(container, ht);
|
||||
if (UNEXPECTED(old_type == IS_FALSE)) {
|
||||
GC_ADDREF(ht);
|
||||
zend_false_to_array_deprecated();
|
||||
if (UNEXPECTED(GC_DELREF(ht) == 0)) {
|
||||
zend_array_destroy(ht);
|
||||
ZEND_VM_C_GOTO(assign_dim_op_ret_null);
|
||||
}
|
||||
}
|
||||
ZVAL_ARR(container, zend_new_array(8));
|
||||
ZEND_VM_C_GOTO(assign_dim_op_new_array);
|
||||
} else {
|
||||
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
|
||||
@@ -2635,10 +2645,6 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
|
||||
FREE_OP_DATA();
|
||||
}
|
||||
} else if (EXPECTED(Z_TYPE_P(object_ptr) <= IS_FALSE)) {
|
||||
if (Z_TYPE_P(object_ptr) == IS_FALSE) {
|
||||
zend_false_to_array_deprecated();
|
||||
}
|
||||
|
||||
if (Z_ISREF_P(orig_object_ptr)
|
||||
&& ZEND_REF_HAS_TYPE_SOURCES(Z_REF_P(orig_object_ptr))
|
||||
&& !zend_verify_ref_array_assignable(Z_REF_P(orig_object_ptr))) {
|
||||
@@ -2646,7 +2652,18 @@ ZEND_VM_C_LABEL(try_assign_dim_array):
|
||||
FREE_OP_DATA();
|
||||
UNDEF_RESULT();
|
||||
} else {
|
||||
ZVAL_ARR(object_ptr, zend_new_array(8));
|
||||
HashTable *ht = zend_new_array(8);
|
||||
zend_uchar old_type = Z_TYPE_P(object_ptr);
|
||||
|
||||
ZVAL_ARR(object_ptr, ht);
|
||||
if (UNEXPECTED(old_type == IS_FALSE)) {
|
||||
GC_ADDREF(ht);
|
||||
zend_false_to_array_deprecated();
|
||||
if (UNEXPECTED(GC_DELREF(ht) == 0)) {
|
||||
zend_array_destroy(ht);
|
||||
ZEND_VM_C_GOTO(assign_dim_error);
|
||||
}
|
||||
}
|
||||
ZEND_VM_C_GOTO(try_assign_dim_array);
|
||||
}
|
||||
} else {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1152,9 +1152,15 @@ static zend_always_inline void ZEND_FASTCALL zend_jit_fetch_dim_obj_helper(zval
|
||||
}
|
||||
ZVAL_UNDEF(result);
|
||||
} else if (Z_TYPE_P(object_ptr) == IS_FALSE) {
|
||||
zend_false_to_array_deprecated();
|
||||
zend_array *arr = zend_new_array(0);
|
||||
ZVAL_ARR(object_ptr, arr);
|
||||
GC_ADDREF(arr);
|
||||
zend_false_to_array_deprecated();
|
||||
if (UNEXPECTED(GC_DELREF(arr) == 0)) {
|
||||
zend_array_destroy(arr);
|
||||
ZVAL_NULL(result);
|
||||
return;
|
||||
}
|
||||
zval *var;
|
||||
if (dim) {
|
||||
if (type == BP_VAR_W) {
|
||||
@@ -1247,12 +1253,6 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim
|
||||
return;
|
||||
}
|
||||
|
||||
if (dim && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {
|
||||
const zend_op *opline = EG(current_execute_data)->opline;
|
||||
zend_jit_undefined_op_helper(opline->op2.var);
|
||||
dim = &EG(uninitialized_zval);
|
||||
}
|
||||
|
||||
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);
|
||||
@@ -1266,9 +1266,17 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim
|
||||
ZVAL_UNDEF(result);
|
||||
}
|
||||
} else if (Z_TYPE_P(object_ptr) == IS_FALSE) {
|
||||
zend_false_to_array_deprecated();
|
||||
zend_array *arr = zend_new_array(0);
|
||||
ZVAL_ARR(object_ptr, arr);
|
||||
GC_ADDREF(arr);
|
||||
zend_false_to_array_deprecated();
|
||||
if (UNEXPECTED(GC_DELREF(arr) == 0)) {
|
||||
zend_array_destroy(arr);
|
||||
if (result) {
|
||||
ZVAL_NULL(result);
|
||||
}
|
||||
return;
|
||||
}
|
||||
zval *var = dim
|
||||
? zend_jit_fetch_dim_w_helper(arr, dim)
|
||||
: zend_hash_next_index_insert_new(arr, &EG(uninitialized_zval));
|
||||
@@ -1284,6 +1292,11 @@ static void ZEND_FASTCALL zend_jit_assign_dim_helper(zval *object_ptr, zval *dim
|
||||
ZVAL_COPY(result, var);
|
||||
}
|
||||
} else {
|
||||
if (dim && UNEXPECTED(Z_TYPE_P(dim) == IS_UNDEF)) {
|
||||
const zend_op *opline = EG(current_execute_data)->opline;
|
||||
zend_jit_undefined_op_helper(opline->op2.var);
|
||||
dim = &EG(uninitialized_zval);
|
||||
}
|
||||
zend_throw_error(NULL, "Cannot use a scalar value as an array");
|
||||
if (result) {
|
||||
ZVAL_UNDEF(result);
|
||||
@@ -1335,9 +1348,14 @@ static void ZEND_FASTCALL zend_jit_assign_dim_op_helper(zval *container, zval *d
|
||||
zend_wrong_string_offset_error();
|
||||
}
|
||||
} else if (Z_TYPE_P(container) == IS_FALSE) {
|
||||
zend_false_to_array_deprecated();
|
||||
zend_array *arr = zend_new_array(0);
|
||||
ZVAL_ARR(container, arr);
|
||||
GC_ADDREF(arr);
|
||||
zend_false_to_array_deprecated();
|
||||
if (UNEXPECTED(GC_DELREF(arr) == 0)) {
|
||||
zend_array_destroy(arr);
|
||||
return;
|
||||
}
|
||||
zval *var = dim
|
||||
? zend_jit_fetch_dim_rw_helper(arr, dim)
|
||||
: zend_hash_next_index_insert_new(arr, &EG(uninitialized_zval));
|
||||
|
||||
Reference in New Issue
Block a user