Skip to content

Commit fc1b467

Browse files
committed
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)
2 parents d41ee53 + 8b5767a commit fc1b467

File tree

4 files changed

+78
-78
lines changed

4 files changed

+78
-78
lines changed

Diff for: ext/opcache/jit/zend_jit_internal.h

+2
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_counter_helper(ZEND_OPCODE_H
230230

231231
void ZEND_FASTCALL zend_jit_copy_extra_args_helper(EXECUTE_DATA_D);
232232
bool ZEND_FASTCALL zend_jit_deprecated_helper(OPLINE_D);
233+
void ZEND_FASTCALL zend_jit_undefined_long_key(EXECUTE_DATA_D);
234+
void ZEND_FASTCALL zend_jit_undefined_string_key(EXECUTE_DATA_D);
233235

234236
zend_constant* ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags);
235237
zend_constant* ZEND_FASTCALL zend_jit_check_constant(const zval *key);

Diff for: ext/opcache/jit/zend_jit_ir.c

+10-78
Original file line numberDiff line numberDiff line change
@@ -2429,92 +2429,22 @@ static int zend_jit_trace_exit_stub(zend_jit_ctx *jit)
24292429

24302430
static int zend_jit_undefined_offset_stub(zend_jit_ctx *jit)
24312431
{
2432-
ir_ref opline = ir_LOAD_A(jit_EX(opline));
2433-
ir_ref ref = ir_LOAD_U32(ir_ADD_OFFSET(opline, offsetof(zend_op, result.var)));
2434-
ir_ref if_const, end1, ref1;
2435-
2436-
if (sizeof(void*) == 8) {
2437-
ref = ir_ZEXT_A(ref);
2438-
}
2439-
jit_set_Z_TYPE_INFO_ref(jit, ir_ADD_A(jit_FP(jit), ref), ir_CONST_U32(IS_NULL));
2440-
2441-
if_const = ir_IF(ir_EQ(ir_LOAD_U8(ir_ADD_OFFSET(opline, offsetof(zend_op, op2_type))), ir_CONST_U8(IS_CONST)));
2442-
2443-
ir_IF_TRUE(if_const);
2444-
#if ZEND_USE_ABS_CONST_ADDR
2445-
ref1 = ir_LOAD_A(ir_ADD_OFFSET(opline, offsetof(zend_op, op2.zv)));
2446-
#else
2447-
ref = ir_LOAD_U32(ir_ADD_OFFSET(opline, offsetof(zend_op, op2.constant)));
2448-
if (sizeof(void*) == 8) {
2449-
ref = ir_SEXT_A(ref);
2450-
}
2451-
ref1 = ir_ADD_A(ref, opline);
2452-
#endif
2453-
2454-
end1 = ir_END();
2455-
2456-
ir_IF_FALSE(if_const);
2457-
ref = ir_LOAD_U32(ir_ADD_OFFSET(opline, offsetof(zend_op, op2.var)));
2458-
if (sizeof(void*) == 8) {
2459-
ref = ir_ZEXT_A(ref);
2432+
if (GCC_GLOBAL_REGS) {
2433+
ir_TAILCALL(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_long_key));
2434+
} else {
2435+
ir_TAILCALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_long_key), jit_FP(jit));
24602436
}
2461-
ref = ir_ADD_A(jit_FP(jit), ref);
2462-
2463-
ir_MERGE_WITH(end1);
2464-
ref = ir_PHI_2(IR_ADDR, ref, ref1);
2465-
2466-
ref = jit_Z_LVAL_ref(jit, ref);
2467-
ir_CALL_3(IR_VOID, ir_CONST_FUNC(zend_error),
2468-
ir_CONST_U8(E_WARNING),
2469-
ir_CONST_ADDR("Undefined array key " ZEND_LONG_FMT),
2470-
ref);
2471-
ir_RETURN(IR_VOID);
24722437

24732438
return 1;
24742439
}
24752440

24762441
static int zend_jit_undefined_key_stub(zend_jit_ctx *jit)
24772442
{
2478-
ir_ref opline = ir_LOAD_A(jit_EX(opline));
2479-
ir_ref ref = ir_LOAD_U32(ir_ADD_OFFSET(opline, offsetof(zend_op, result.var)));
2480-
ir_ref if_const, end1, ref1;
2481-
2482-
if (sizeof(void*) == 8) {
2483-
ref = ir_ZEXT_A(ref);
2484-
}
2485-
jit_set_Z_TYPE_INFO_ref(jit, ir_ADD_A(jit_FP(jit), ref), ir_CONST_U32(IS_NULL));
2486-
2487-
if_const = ir_IF(ir_EQ(ir_LOAD_U8(ir_ADD_OFFSET(opline, offsetof(zend_op, op2_type))), ir_CONST_U8(IS_CONST)));
2488-
2489-
ir_IF_TRUE(if_const);
2490-
#if ZEND_USE_ABS_CONST_ADDR
2491-
ref1 = ir_LOAD_A(ir_ADD_OFFSET(opline, offsetof(zend_op, op2.zv)));
2492-
#else
2493-
ref = ir_LOAD_U32(ir_ADD_OFFSET(opline, offsetof(zend_op, op2.constant)));
2494-
if (sizeof(void*) == 8) {
2495-
ref = ir_SEXT_A(ref);
2496-
}
2497-
ref1 = ir_ADD_A(ref, opline);
2498-
#endif
2499-
2500-
end1 = ir_END();
2501-
2502-
ir_IF_FALSE(if_const);
2503-
ref = ir_LOAD_U32(ir_ADD_OFFSET(opline, offsetof(zend_op, op2.var)));
2504-
if (sizeof(void*) == 8) {
2505-
ref = ir_ZEXT_A(ref);
2443+
if (GCC_GLOBAL_REGS) {
2444+
ir_TAILCALL(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_string_key));
2445+
} else {
2446+
ir_TAILCALL_1(IR_VOID, ir_CONST_FC_FUNC(zend_jit_undefined_string_key), jit_FP(jit));
25062447
}
2507-
ref = ir_ADD_A(jit_FP(jit), ref);
2508-
2509-
ir_MERGE_WITH(end1);
2510-
ref = ir_PHI_2(IR_ADDR, ref, ref1);
2511-
2512-
ref = ir_ADD_OFFSET(jit_Z_PTR_ref(jit, ref), offsetof(zend_string, val));
2513-
ir_CALL_3(IR_VOID, ir_CONST_FUNC(zend_error),
2514-
ir_CONST_U8(E_WARNING),
2515-
ir_CONST_ADDR("Undefined array key \"%s\""),
2516-
ref);
2517-
ir_RETURN(IR_VOID);
25182448

25192449
return 1;
25202450
}
@@ -3039,6 +2969,8 @@ static void zend_jit_setup_disasm(void)
30392969
REGISTER_HELPER(zend_jit_free_trampoline_helper);
30402970
REGISTER_HELPER(zend_jit_verify_return_slow);
30412971
REGISTER_HELPER(zend_jit_deprecated_helper);
2972+
REGISTER_HELPER(zend_jit_undefined_long_key);
2973+
REGISTER_HELPER(zend_jit_undefined_string_key);
30422974
REGISTER_HELPER(zend_jit_copy_extra_args_helper);
30432975
REGISTER_HELPER(zend_jit_vm_stack_free_args_helper);
30442976
REGISTER_HELPER(zend_free_extra_named_params);

Diff for: ext/opcache/jit/zend_jit_vm_helpers.c

+37
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,43 @@ bool ZEND_FASTCALL zend_jit_deprecated_helper(OPLINE_D)
194194
return 1;
195195
}
196196

197+
void ZEND_FASTCALL zend_jit_undefined_long_key(EXECUTE_DATA_D)
198+
{
199+
const zend_op *opline = EX(opline);
200+
zval *result = EX_VAR(opline->result.var);
201+
zval *dim;
202+
203+
ZVAL_NULL(result);
204+
if (opline->op2_type == IS_CONST) {
205+
dim = RT_CONSTANT(opline, opline->op2);
206+
} else {
207+
dim = EX_VAR(opline->op2.var);
208+
}
209+
ZEND_ASSERT(Z_TYPE_P(dim) == IS_LONG);
210+
zend_error(E_WARNING, "Undefined array key " ZEND_LONG_FMT, Z_LVAL_P(dim));
211+
}
212+
213+
void ZEND_FASTCALL zend_jit_undefined_string_key(EXECUTE_DATA_D)
214+
{
215+
const zend_op *opline = EX(opline);
216+
zval *result = EX_VAR(opline->result.var);
217+
zval *dim;
218+
zend_ulong lval;
219+
220+
ZVAL_NULL(result);
221+
if (opline->op2_type == IS_CONST) {
222+
dim = RT_CONSTANT(opline, opline->op2);
223+
} else {
224+
dim = EX_VAR(opline->op2.var);
225+
}
226+
ZEND_ASSERT(Z_TYPE_P(dim) == IS_STRING);
227+
if (ZEND_HANDLE_NUMERIC(Z_STR_P(dim), lval)) {
228+
zend_error(E_WARNING, "Undefined array key " ZEND_LONG_FMT, lval);
229+
} else {
230+
zend_error(E_WARNING, "Undefined array key \"%s\"", Z_STRVAL_P(dim));
231+
}
232+
}
233+
197234
ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_profile_helper(ZEND_OPCODE_HANDLER_ARGS)
198235
{
199236
zend_op_array *op_array = (zend_op_array*)EX(func);

Diff for: ext/opcache/tests/jit/gh12812.phpt

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
GH-12812: JIT: Integer string in variable used as offset produces wrong undefined array key warning
3+
--INI--
4+
opcache.enable=1
5+
opcache.enable_cli=1
6+
--FILE--
7+
<?php
8+
9+
$container = [];
10+
$dimension = '7';
11+
12+
try {
13+
var_dump($container['7']);
14+
} catch (\Throwable $e) {
15+
echo $e->getMessage(), "\n";
16+
}
17+
try {
18+
var_dump($container[$dimension]);
19+
} catch (\Throwable $e) {
20+
echo $e->getMessage(), "\n";
21+
}
22+
23+
?>
24+
--EXPECTF--
25+
Warning: Undefined array key 7 in %s on line %d
26+
NULL
27+
28+
Warning: Undefined array key 7 in %s on line %d
29+
NULL

0 commit comments

Comments
 (0)