mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.3'
* PHP-8.3: Fixed GH-12812: Integer string in variable used as offset produces wrong undefined array key warning (#12817)
This commit is contained in:
@@ -230,6 +230,8 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_counter_helper(ZEND_OPCODE_H
|
||||
|
||||
void ZEND_FASTCALL zend_jit_copy_extra_args_helper(EXECUTE_DATA_D);
|
||||
bool ZEND_FASTCALL zend_jit_deprecated_helper(OPLINE_D);
|
||||
void ZEND_FASTCALL zend_jit_undefined_long_key(EXECUTE_DATA_D);
|
||||
void ZEND_FASTCALL zend_jit_undefined_string_key(EXECUTE_DATA_D);
|
||||
|
||||
zend_constant* ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags);
|
||||
zend_constant* ZEND_FASTCALL zend_jit_check_constant(const zval *key);
|
||||
|
||||
@@ -2429,92 +2429,22 @@ static int zend_jit_trace_exit_stub(zend_jit_ctx *jit)
|
||||
|
||||
static int zend_jit_undefined_offset_stub(zend_jit_ctx *jit)
|
||||
{
|
||||
ir_ref opline = ir_LOAD_A(jit_EX(opline));
|
||||
ir_ref ref = ir_LOAD_U32(ir_ADD_OFFSET(opline, offsetof(zend_op, result.var)));
|
||||
ir_ref if_const, end1, ref1;
|
||||
|
||||
if (sizeof(void*) == 8) {
|
||||
ref = ir_ZEXT_A(ref);
|
||||
if (GCC_GLOBAL_REGS) {
|
||||
ir_TAILCALL(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_long_key));
|
||||
} else {
|
||||
ir_TAILCALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_long_key), jit_FP(jit));
|
||||
}
|
||||
jit_set_Z_TYPE_INFO_ref(jit, ir_ADD_A(jit_FP(jit), ref), ir_CONST_U32(IS_NULL));
|
||||
|
||||
if_const = ir_IF(ir_EQ(ir_LOAD_U8(ir_ADD_OFFSET(opline, offsetof(zend_op, op2_type))), ir_CONST_U8(IS_CONST)));
|
||||
|
||||
ir_IF_TRUE(if_const);
|
||||
#if ZEND_USE_ABS_CONST_ADDR
|
||||
ref1 = ir_LOAD_A(ir_ADD_OFFSET(opline, offsetof(zend_op, op2.zv)));
|
||||
#else
|
||||
ref = ir_LOAD_U32(ir_ADD_OFFSET(opline, offsetof(zend_op, op2.constant)));
|
||||
if (sizeof(void*) == 8) {
|
||||
ref = ir_SEXT_A(ref);
|
||||
}
|
||||
ref1 = ir_ADD_A(ref, opline);
|
||||
#endif
|
||||
|
||||
end1 = ir_END();
|
||||
|
||||
ir_IF_FALSE(if_const);
|
||||
ref = ir_LOAD_U32(ir_ADD_OFFSET(opline, offsetof(zend_op, op2.var)));
|
||||
if (sizeof(void*) == 8) {
|
||||
ref = ir_ZEXT_A(ref);
|
||||
}
|
||||
ref = ir_ADD_A(jit_FP(jit), ref);
|
||||
|
||||
ir_MERGE_WITH(end1);
|
||||
ref = ir_PHI_2(IR_ADDR, ref, ref1);
|
||||
|
||||
ref = jit_Z_LVAL_ref(jit, ref);
|
||||
ir_CALL_3(IR_VOID, ir_CONST_FUNC(zend_error),
|
||||
ir_CONST_U8(E_WARNING),
|
||||
ir_CONST_ADDR("Undefined array key " ZEND_LONG_FMT),
|
||||
ref);
|
||||
ir_RETURN(IR_VOID);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int zend_jit_undefined_key_stub(zend_jit_ctx *jit)
|
||||
{
|
||||
ir_ref opline = ir_LOAD_A(jit_EX(opline));
|
||||
ir_ref ref = ir_LOAD_U32(ir_ADD_OFFSET(opline, offsetof(zend_op, result.var)));
|
||||
ir_ref if_const, end1, ref1;
|
||||
|
||||
if (sizeof(void*) == 8) {
|
||||
ref = ir_ZEXT_A(ref);
|
||||
if (GCC_GLOBAL_REGS) {
|
||||
ir_TAILCALL(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_string_key));
|
||||
} else {
|
||||
ir_TAILCALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_string_key), jit_FP(jit));
|
||||
}
|
||||
jit_set_Z_TYPE_INFO_ref(jit, ir_ADD_A(jit_FP(jit), ref), ir_CONST_U32(IS_NULL));
|
||||
|
||||
if_const = ir_IF(ir_EQ(ir_LOAD_U8(ir_ADD_OFFSET(opline, offsetof(zend_op, op2_type))), ir_CONST_U8(IS_CONST)));
|
||||
|
||||
ir_IF_TRUE(if_const);
|
||||
#if ZEND_USE_ABS_CONST_ADDR
|
||||
ref1 = ir_LOAD_A(ir_ADD_OFFSET(opline, offsetof(zend_op, op2.zv)));
|
||||
#else
|
||||
ref = ir_LOAD_U32(ir_ADD_OFFSET(opline, offsetof(zend_op, op2.constant)));
|
||||
if (sizeof(void*) == 8) {
|
||||
ref = ir_SEXT_A(ref);
|
||||
}
|
||||
ref1 = ir_ADD_A(ref, opline);
|
||||
#endif
|
||||
|
||||
end1 = ir_END();
|
||||
|
||||
ir_IF_FALSE(if_const);
|
||||
ref = ir_LOAD_U32(ir_ADD_OFFSET(opline, offsetof(zend_op, op2.var)));
|
||||
if (sizeof(void*) == 8) {
|
||||
ref = ir_ZEXT_A(ref);
|
||||
}
|
||||
ref = ir_ADD_A(jit_FP(jit), ref);
|
||||
|
||||
ir_MERGE_WITH(end1);
|
||||
ref = ir_PHI_2(IR_ADDR, ref, ref1);
|
||||
|
||||
ref = ir_ADD_OFFSET(jit_Z_PTR_ref(jit, ref), offsetof(zend_string, val));
|
||||
ir_CALL_3(IR_VOID, ir_CONST_FUNC(zend_error),
|
||||
ir_CONST_U8(E_WARNING),
|
||||
ir_CONST_ADDR("Undefined array key \"%s\""),
|
||||
ref);
|
||||
ir_RETURN(IR_VOID);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -3039,6 +2969,8 @@ static void zend_jit_setup_disasm(void)
|
||||
REGISTER_HELPER(zend_jit_free_trampoline_helper);
|
||||
REGISTER_HELPER(zend_jit_verify_return_slow);
|
||||
REGISTER_HELPER(zend_jit_deprecated_helper);
|
||||
REGISTER_HELPER(zend_jit_undefined_long_key);
|
||||
REGISTER_HELPER(zend_jit_undefined_string_key);
|
||||
REGISTER_HELPER(zend_jit_copy_extra_args_helper);
|
||||
REGISTER_HELPER(zend_jit_vm_stack_free_args_helper);
|
||||
REGISTER_HELPER(zend_free_extra_named_params);
|
||||
|
||||
@@ -194,6 +194,43 @@ bool ZEND_FASTCALL zend_jit_deprecated_helper(OPLINE_D)
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ZEND_FASTCALL zend_jit_undefined_long_key(EXECUTE_DATA_D)
|
||||
{
|
||||
const zend_op *opline = EX(opline);
|
||||
zval *result = EX_VAR(opline->result.var);
|
||||
zval *dim;
|
||||
|
||||
ZVAL_NULL(result);
|
||||
if (opline->op2_type == IS_CONST) {
|
||||
dim = RT_CONSTANT(opline, opline->op2);
|
||||
} else {
|
||||
dim = EX_VAR(opline->op2.var);
|
||||
}
|
||||
ZEND_ASSERT(Z_TYPE_P(dim) == IS_LONG);
|
||||
zend_error(E_WARNING, "Undefined array key " ZEND_LONG_FMT, Z_LVAL_P(dim));
|
||||
}
|
||||
|
||||
void ZEND_FASTCALL zend_jit_undefined_string_key(EXECUTE_DATA_D)
|
||||
{
|
||||
const zend_op *opline = EX(opline);
|
||||
zval *result = EX_VAR(opline->result.var);
|
||||
zval *dim;
|
||||
zend_ulong lval;
|
||||
|
||||
ZVAL_NULL(result);
|
||||
if (opline->op2_type == IS_CONST) {
|
||||
dim = RT_CONSTANT(opline, opline->op2);
|
||||
} else {
|
||||
dim = EX_VAR(opline->op2.var);
|
||||
}
|
||||
ZEND_ASSERT(Z_TYPE_P(dim) == IS_STRING);
|
||||
if (ZEND_HANDLE_NUMERIC(Z_STR_P(dim), lval)) {
|
||||
zend_error(E_WARNING, "Undefined array key " ZEND_LONG_FMT, lval);
|
||||
} else {
|
||||
zend_error(E_WARNING, "Undefined array key \"%s\"", Z_STRVAL_P(dim));
|
||||
}
|
||||
}
|
||||
|
||||
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_profile_helper(ZEND_OPCODE_HANDLER_ARGS)
|
||||
{
|
||||
zend_op_array *op_array = (zend_op_array*)EX(func);
|
||||
|
||||
29
ext/opcache/tests/jit/gh12812.phpt
Normal file
29
ext/opcache/tests/jit/gh12812.phpt
Normal file
@@ -0,0 +1,29 @@
|
||||
--TEST--
|
||||
GH-12812: JIT: Integer string in variable used as offset produces wrong undefined array key warning
|
||||
--INI--
|
||||
opcache.enable=1
|
||||
opcache.enable_cli=1
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
$container = [];
|
||||
$dimension = '7';
|
||||
|
||||
try {
|
||||
var_dump($container['7']);
|
||||
} catch (\Throwable $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
try {
|
||||
var_dump($container[$dimension]);
|
||||
} catch (\Throwable $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Warning: Undefined array key 7 in %s on line %d
|
||||
NULL
|
||||
|
||||
Warning: Undefined array key 7 in %s on line %d
|
||||
NULL
|
||||
Reference in New Issue
Block a user