mirror of
https://github.com/php/php-src.git
synced 2024-11-28 20:34:29 +08:00
Better fix for bug #68446
This commit is contained in:
parent
0ca47ba8d8
commit
e116595e63
@ -1931,8 +1931,11 @@ void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initializ
|
||||
if (class_type->u.constant.type == IS_ARRAY) {
|
||||
cur_arg_info->type_hint = IS_ARRAY;
|
||||
if (op == ZEND_RECV_INIT) {
|
||||
if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) {
|
||||
if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) {
|
||||
cur_arg_info->allow_null = 1;
|
||||
} else if (IS_CONSTANT_TYPE(Z_TYPE(initialization->u.constant))) {
|
||||
/* delay constant resolution and check to run-time */
|
||||
cur_arg_info->allow_null = 0;
|
||||
} else if (Z_TYPE(initialization->u.constant) != IS_ARRAY) {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with array type hint can only be an array or NULL");
|
||||
}
|
||||
@ -1940,8 +1943,11 @@ void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initializ
|
||||
} else if (class_type->u.constant.type == IS_CALLABLE) {
|
||||
cur_arg_info->type_hint = IS_CALLABLE;
|
||||
if (op == ZEND_RECV_INIT) {
|
||||
if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) {
|
||||
if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) {
|
||||
cur_arg_info->allow_null = 1;
|
||||
} else if (IS_CONSTANT_TYPE(Z_TYPE(initialization->u.constant))) {
|
||||
/* delay constant resolution and check to run-time */
|
||||
cur_arg_info->allow_null = 0;
|
||||
} else {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with callable type hint can only be NULL");
|
||||
}
|
||||
@ -1955,8 +1961,11 @@ void zend_do_receive_param(zend_uchar op, znode *varname, const znode *initializ
|
||||
cur_arg_info->class_name = Z_STRVAL(class_type->u.constant);
|
||||
cur_arg_info->class_name_len = Z_STRLEN(class_type->u.constant);
|
||||
if (op == ZEND_RECV_INIT) {
|
||||
if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL")) || Z_TYPE(initialization->u.constant) == IS_CONSTANT_AST) {
|
||||
if (Z_TYPE(initialization->u.constant) == IS_NULL || (Z_TYPE(initialization->u.constant) == IS_CONSTANT && !strcasecmp(Z_STRVAL(initialization->u.constant), "NULL"))) {
|
||||
cur_arg_info->allow_null = 1;
|
||||
} else if (IS_CONSTANT_TYPE(Z_TYPE(initialization->u.constant))) {
|
||||
/* delay constant resolution and check to run-time */
|
||||
cur_arg_info->allow_null = 0;
|
||||
} else {
|
||||
zend_error_noreturn(E_COMPILE_ERROR, "Default value for parameters with a class type hint can only be NULL");
|
||||
}
|
||||
|
@ -608,7 +608,22 @@ ZEND_API int zend_verify_arg_error(int error_type, const zend_function *zf, zend
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg, ulong fetch_type TSRMLS_DC)
|
||||
static int is_null_constant(zval *default_value)
|
||||
{
|
||||
if (IS_CONSTANT_TYPE(Z_TYPE_P(default_value))) {
|
||||
zval constant = *default_value;
|
||||
zval *constant_ptr = &constant;
|
||||
|
||||
zval_update_constant(&constant_ptr, 0 TSRMLS_CC);
|
||||
if (Z_TYPE(constant) == IS_NULL) {
|
||||
return 1;
|
||||
}
|
||||
zval_dtor(&constant);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zval *arg, ulong fetch_type, zval *default_value TSRMLS_DC)
|
||||
{
|
||||
zend_arg_info *cur_arg_info;
|
||||
char *need_msg;
|
||||
@ -638,7 +653,7 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
|
||||
if (!ce || !instanceof_function(Z_OBJCE_P(arg), ce TSRMLS_CC)) {
|
||||
return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, "instance of ", Z_OBJCE_P(arg)->name TSRMLS_CC);
|
||||
}
|
||||
} else if (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null) {
|
||||
} else if (Z_TYPE_P(arg) != IS_NULL || !(cur_arg_info->allow_null || (default_value && is_null_constant(default_value)))) {
|
||||
need_msg = zend_verify_arg_class_kind(cur_arg_info, fetch_type, &class_name, &ce TSRMLS_CC);
|
||||
return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, need_msg, class_name, zend_zval_type_name(arg), "" TSRMLS_CC);
|
||||
}
|
||||
@ -649,7 +664,7 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
|
||||
return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", "none", "" TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
|
||||
if (Z_TYPE_P(arg) != IS_ARRAY && (Z_TYPE_P(arg) != IS_NULL || !(cur_arg_info->allow_null || (default_value && is_null_constant(default_value))))) {
|
||||
return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be of the type array", "", zend_zval_type_name(arg), "" TSRMLS_CC);
|
||||
}
|
||||
break;
|
||||
@ -658,7 +673,7 @@ static inline int zend_verify_arg_type(zend_function *zf, zend_uint arg_num, zva
|
||||
if (!arg) {
|
||||
return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", "none", "" TSRMLS_CC);
|
||||
}
|
||||
if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL TSRMLS_CC) && (Z_TYPE_P(arg) != IS_NULL || !cur_arg_info->allow_null)) {
|
||||
if (!zend_is_callable(arg, IS_CALLABLE_CHECK_SILENT, NULL TSRMLS_CC) && (Z_TYPE_P(arg) != IS_NULL || !(cur_arg_info->allow_null || (default_value && is_null_constant(default_value))))) {
|
||||
return zend_verify_arg_error(E_RECOVERABLE_ERROR, zf, arg_num, "be callable", "", zend_zval_type_name(arg), "" TSRMLS_CC);
|
||||
}
|
||||
break;
|
||||
|
@ -1961,7 +1961,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
|
||||
void **p = EX(function_state).arguments - num_args;
|
||||
|
||||
for (i = 0; i < num_args; ++i, ++p) {
|
||||
zend_verify_arg_type(fbc, i + 1, (zval *) *p, 0 TSRMLS_CC);
|
||||
zend_verify_arg_type(fbc, i + 1, (zval *) *p, 0, NULL TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3374,7 +3374,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (UNEXPECTED(param == NULL)) {
|
||||
if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value TSRMLS_CC)) {
|
||||
if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value, NULL TSRMLS_CC)) {
|
||||
const char *space;
|
||||
const char *class_name;
|
||||
zend_execute_data *ptr;
|
||||
@ -3396,7 +3396,7 @@ ZEND_VM_HANDLER(63, ZEND_RECV, ANY, ANY)
|
||||
} else {
|
||||
zval **var_ptr;
|
||||
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value, NULL TSRMLS_CC);
|
||||
var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
|
||||
Z_DELREF_PP(var_ptr);
|
||||
*var_ptr = *param;
|
||||
@ -3438,7 +3438,7 @@ ZEND_VM_HANDLER(64, ZEND_RECV_INIT, ANY, CONST)
|
||||
Z_ADDREF_P(assignment_value);
|
||||
}
|
||||
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value, opline->op2.zv TSRMLS_CC);
|
||||
var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
|
||||
zval_ptr_dtor(var_ptr);
|
||||
*var_ptr = assignment_value;
|
||||
@ -3469,7 +3469,7 @@ ZEND_VM_HANDLER(164, ZEND_RECV_VARIADIC, ANY, ANY)
|
||||
|
||||
for (; arg_num <= arg_count; ++arg_num) {
|
||||
zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value, NULL TSRMLS_CC);
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(params), param, sizeof(zval *), NULL);
|
||||
Z_ADDREF_PP(param);
|
||||
}
|
||||
|
@ -541,7 +541,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
|
||||
void **p = EX(function_state).arguments - num_args;
|
||||
|
||||
for (i = 0; i < num_args; ++i, ++p) {
|
||||
zend_verify_arg_type(fbc, i + 1, (zval *) *p, 0 TSRMLS_CC);
|
||||
zend_verify_arg_type(fbc, i + 1, (zval *) *p, 0, NULL TSRMLS_CC);
|
||||
}
|
||||
}
|
||||
|
||||
@ -861,7 +861,7 @@ static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
|
||||
SAVE_OPLINE();
|
||||
if (UNEXPECTED(param == NULL)) {
|
||||
if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value TSRMLS_CC)) {
|
||||
if (zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, NULL, opline->extended_value, NULL TSRMLS_CC)) {
|
||||
const char *space;
|
||||
const char *class_name;
|
||||
zend_execute_data *ptr;
|
||||
@ -883,7 +883,7 @@ static int ZEND_FASTCALL ZEND_RECV_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
|
||||
} else {
|
||||
zval **var_ptr;
|
||||
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value, NULL TSRMLS_CC);
|
||||
var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
|
||||
Z_DELREF_PP(var_ptr);
|
||||
*var_ptr = *param;
|
||||
@ -916,7 +916,7 @@ static int ZEND_FASTCALL ZEND_RECV_VARIADIC_SPEC_HANDLER(ZEND_OPCODE_HANDLER_AR
|
||||
|
||||
for (; arg_num <= arg_count; ++arg_num) {
|
||||
zval **param = zend_vm_stack_get_arg(arg_num TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, *param, opline->extended_value, NULL TSRMLS_CC);
|
||||
zend_hash_next_index_insert(Z_ARRVAL_P(params), param, sizeof(zval *), NULL);
|
||||
Z_ADDREF_PP(param);
|
||||
}
|
||||
@ -1643,7 +1643,7 @@ static int ZEND_FASTCALL ZEND_RECV_INIT_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_
|
||||
Z_ADDREF_P(assignment_value);
|
||||
}
|
||||
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value TSRMLS_CC);
|
||||
zend_verify_arg_type((zend_function *) EG(active_op_array), arg_num, assignment_value, opline->extended_value, opline->op2.zv TSRMLS_CC);
|
||||
var_ptr = _get_zval_ptr_ptr_cv_BP_VAR_W(execute_data, opline->result.var TSRMLS_CC);
|
||||
zval_ptr_dtor(var_ptr);
|
||||
*var_ptr = assignment_value;
|
||||
|
Loading…
Reference in New Issue
Block a user