mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Fix comp-time and constant evaluation of dynamic class constant fetch
Fixes GH-10486 Fixes oss-fuzz #55436 Fixes oss-fuzz #55472 Closes GH-10487
This commit is contained in:
parent
f291d37a1a
commit
35a36b13e5
@ -670,7 +670,9 @@ void zend_optimizer_compact_literals(zend_op_array *op_array, zend_optimizer_ctx
|
||||
}
|
||||
break;
|
||||
case ZEND_FETCH_CLASS_CONSTANT:
|
||||
if (opline->op1_type == IS_CONST && opline->op2_type == IS_CONST) {
|
||||
if (opline->op1_type == IS_CONST
|
||||
&& opline->op2_type == IS_CONST
|
||||
&& Z_TYPE(op_array->literals[opline->op2.constant]) == IS_STRING) {
|
||||
// op1/op2 class_const
|
||||
opline->extended_value = add_static_slot(&hash, op_array,
|
||||
opline->op1.constant,
|
||||
|
11
Zend/tests/gh10486.phpt
Normal file
11
Zend/tests/gh10486.phpt
Normal file
@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
Assertion error when attempting comp-time eval of dynamic class constant fetch
|
||||
--FILE--
|
||||
<?php
|
||||
y::{5}::y;
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Class "y" not found in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
11
Zend/tests/gh10486_2.phpt
Normal file
11
Zend/tests/gh10486_2.phpt
Normal file
@ -0,0 +1,11 @@
|
||||
--TEST--
|
||||
Assertion error when attempting constant eval of dynamic class constant fetch
|
||||
--FILE--
|
||||
<?php
|
||||
const y = y::{y};
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Undefined constant "y" in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
@ -834,7 +834,15 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
|
||||
case ZEND_AST_CLASS_CONST:
|
||||
{
|
||||
zend_string *class_name = zend_ast_get_str(ast->child[0]);
|
||||
zend_string *const_name = zend_ast_get_str(ast->child[1]);
|
||||
if (UNEXPECTED(zend_ast_evaluate_ex(&op2, ast->child[1], scope, &short_circuited, ctx) != SUCCESS)) {
|
||||
return FAILURE;
|
||||
}
|
||||
if (UNEXPECTED(Z_TYPE(op2) != IS_STRING)) {
|
||||
zend_invalid_class_constant_type_error(Z_TYPE(op2));
|
||||
zval_ptr_dtor_nogc(&op2);
|
||||
return FAILURE;
|
||||
}
|
||||
zend_string *const_name = Z_STR(op2);
|
||||
|
||||
zend_string *previous_filename;
|
||||
zend_long previous_lineno;
|
||||
@ -852,9 +860,11 @@ ZEND_API zend_result ZEND_FASTCALL zend_ast_evaluate_inner(
|
||||
|
||||
if (UNEXPECTED(zv == NULL)) {
|
||||
ZVAL_UNDEF(result);
|
||||
zval_ptr_dtor_nogc(&op2);
|
||||
return FAILURE;
|
||||
}
|
||||
ZVAL_COPY_OR_DUP(result, zv);
|
||||
zval_ptr_dtor_nogc(&op2);
|
||||
break;
|
||||
}
|
||||
case ZEND_AST_NEW:
|
||||
|
@ -10742,6 +10742,11 @@ static void zend_eval_const_expr(zend_ast **ast_ptr) /* {{{ */
|
||||
zend_ast *name_ast;
|
||||
zend_string *resolved_name;
|
||||
|
||||
if (UNEXPECTED(ast->child[1]->kind != ZEND_AST_ZVAL
|
||||
|| Z_TYPE_P(zend_ast_get_zval(ast->child[1])) != IS_STRING)) {
|
||||
return;
|
||||
}
|
||||
|
||||
zend_eval_const_expr(&ast->child[0]);
|
||||
zend_eval_const_expr(&ast->child[1]);
|
||||
|
||||
|
@ -894,6 +894,11 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modificati
|
||||
ZSTR_VAL(info->ce->name), zend_get_unmangled_property_name(info->name));
|
||||
}
|
||||
|
||||
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(zend_uchar type)
|
||||
{
|
||||
zend_type_error("Cannot use value of type %s as class constant name", zend_get_type_by_const(type));
|
||||
}
|
||||
|
||||
static const zend_class_entry *resolve_single_class_type(zend_string *name, const zend_class_entry *self_ce) {
|
||||
if (zend_string_equals_literal_ci(name, "self")) {
|
||||
return self_ce;
|
||||
|
@ -82,6 +82,8 @@ ZEND_API ZEND_COLD void zend_wrong_string_offset_error(void);
|
||||
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_modification_error(const zend_property_info *info);
|
||||
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_readonly_property_indirect_modification_error(const zend_property_info *info);
|
||||
|
||||
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_invalid_class_constant_type_error(zend_uchar type);
|
||||
|
||||
ZEND_API bool zend_verify_scalar_type_hint(uint32_t type_mask, zval *arg, bool strict, bool is_internal_arg);
|
||||
ZEND_API ZEND_COLD void zend_verify_arg_error(
|
||||
const zend_function *zf, const zend_arg_info *arg_info, uint32_t arg_num, zval *value);
|
||||
|
@ -5922,7 +5922,7 @@ ZEND_VM_HANDLER(181, ZEND_FETCH_CLASS_CONSTANT, VAR|CONST|UNUSED|CLASS_FETCH, CO
|
||||
|
||||
constant_zv = GET_OP2_ZVAL_PTR_DEREF(BP_VAR_R);
|
||||
if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) {
|
||||
zend_type_error("Cannot use value of type %s as class constant name", zend_get_type_by_const(Z_TYPE_P(constant_zv)));
|
||||
zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
FREE_OP2();
|
||||
HANDLE_EXCEPTION();
|
||||
|
12
Zend/zend_vm_execute.h
generated
12
Zend/zend_vm_execute.h
generated
@ -7203,7 +7203,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
|
||||
|
||||
constant_zv = RT_CONSTANT(opline, opline->op2);
|
||||
if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) {
|
||||
zend_type_error("Cannot use value of type %s as class constant name", zend_get_type_by_const(Z_TYPE_P(constant_zv)));
|
||||
zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
|
||||
HANDLE_EXCEPTION();
|
||||
@ -8358,7 +8358,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_CONS
|
||||
|
||||
constant_zv = _get_zval_ptr_tmpvarcv(opline->op2_type, opline->op2, BP_VAR_R EXECUTE_DATA_CC);
|
||||
if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) {
|
||||
zend_type_error("Cannot use value of type %s as class constant name", zend_get_type_by_const(Z_TYPE_P(constant_zv)));
|
||||
zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
FREE_OP(opline->op2_type, opline->op2.var);
|
||||
HANDLE_EXCEPTION();
|
||||
@ -25011,7 +25011,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
|
||||
|
||||
constant_zv = RT_CONSTANT(opline, opline->op2);
|
||||
if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) {
|
||||
zend_type_error("Cannot use value of type %s as class constant name", zend_get_type_by_const(Z_TYPE_P(constant_zv)));
|
||||
zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
|
||||
HANDLE_EXCEPTION();
|
||||
@ -25574,7 +25574,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_VAR_
|
||||
|
||||
constant_zv = _get_zval_ptr_tmpvarcv(opline->op2_type, opline->op2, BP_VAR_R EXECUTE_DATA_CC);
|
||||
if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) {
|
||||
zend_type_error("Cannot use value of type %s as class constant name", zend_get_type_by_const(Z_TYPE_P(constant_zv)));
|
||||
zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
FREE_OP(opline->op2_type, opline->op2.var);
|
||||
HANDLE_EXCEPTION();
|
||||
@ -33999,7 +33999,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
|
||||
|
||||
constant_zv = RT_CONSTANT(opline, opline->op2);
|
||||
if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) {
|
||||
zend_type_error("Cannot use value of type %s as class constant name", zend_get_type_by_const(Z_TYPE_P(constant_zv)));
|
||||
zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
|
||||
HANDLE_EXCEPTION();
|
||||
@ -34352,7 +34352,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CLASS_CONSTANT_SPEC_UNUS
|
||||
|
||||
constant_zv = _get_zval_ptr_tmpvarcv(opline->op2_type, opline->op2, BP_VAR_R EXECUTE_DATA_CC);
|
||||
if (UNEXPECTED(Z_TYPE_P(constant_zv) != IS_STRING)) {
|
||||
zend_type_error("Cannot use value of type %s as class constant name", zend_get_type_by_const(Z_TYPE_P(constant_zv)));
|
||||
zend_invalid_class_constant_type_error(Z_TYPE_P(constant_zv));
|
||||
ZVAL_UNDEF(EX_VAR(opline->result.var));
|
||||
FREE_OP(opline->op2_type, opline->op2.var);
|
||||
HANDLE_EXCEPTION();
|
||||
|
Loading…
Reference in New Issue
Block a user