Skip to content

Commit 8b5767a

Browse files
committed
Merge branch 'PHP-8.2' into PHP-8.3
* PHP-8.2: Fixed GH-12812: Integer string in variable used as offset produces wrong undefined array key warning (#12817)
2 parents de0cef4 + 39a813d commit 8b5767a

File tree

6 files changed

+86
-159
lines changed

6 files changed

+86
-159
lines changed

ext/opcache/jit/zend_jit_arm64.dasc

Lines changed: 8 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -2023,39 +2023,10 @@ static int zend_jit_undefined_offset_ex_stub(dasm_State **Dst)
20232023
static int zend_jit_undefined_offset_stub(dasm_State **Dst)
20242024
{
20252025
|->undefined_offset:
2026-
#ifdef __APPLE__
2027-
| stp x29, x30, [sp, # -16]!
2028-
| mov x29, sp
2029-
#endif
2030-
| //sub r4, 8
2031-
| ldr REG0, EX->opline
2032-
| ldr REG1w, OP:REG0->result.var
2033-
| add REG1, REG1, FP
2034-
| SET_Z_TYPE_INFO REG1, IS_NULL, TMP1w
2035-
| ldrb REG1w, OP:REG0->op2_type
2036-
| cmp REG1w, #IS_CONST
2037-
| bne >2
2038-
| ldrsw REG1, OP:REG0->op2.constant
2039-
| add REG0, REG0, REG1
2040-
| b >3
2041-
|2:
2042-
| ldr REG0w, OP:REG0->op2.var
2043-
| add REG0, REG0, FP
2044-
|3:
2045-
| mov CARG1, #E_WARNING
2046-
| LOAD_ADDR CARG2, "Undefined array key " ZEND_LONG_FMT
2047-
| ldr CARG3, [REG0]
2048-
#ifdef __APPLE__
2049-
| str CARG3, [sp, #-16]!
2050-
| EXT_CALL zend_error, REG0
2051-
| add sp, sp, #16
2052-
| ldp x29, x30, [sp], #16
2053-
| ret
2054-
#else
2055-
| EXT_JMP zend_error, REG0 // tail call
2056-
| //add r4, 8 // stack alignment
2057-
| //ret
2058-
#endif
2026+
|| if (!GCC_GLOBAL_REGS) {
2027+
| mov FCARG1x, FP
2028+
|| }
2029+
| EXT_JMP zend_jit_undefined_long_key, REG0
20592030

20602031
return 1;
20612032
}
@@ -2072,40 +2043,10 @@ static int zend_jit_undefined_index_ex_stub(dasm_State **Dst)
20722043
static int zend_jit_undefined_index_stub(dasm_State **Dst)
20732044
{
20742045
|->undefined_index:
2075-
#ifdef __APPLE__
2076-
| stp x29, x30, [sp, # -16]!
2077-
| mov x29, sp
2078-
#endif
2079-
| //sub r4, 8
2080-
| ldr REG0, EX->opline
2081-
| ldr REG1w, OP:REG0->result.var
2082-
| add REG1, REG1, FP
2083-
| SET_Z_TYPE_INFO REG1, IS_NULL, TMP1w
2084-
| ldrb REG1w, OP:REG0->op2_type
2085-
| cmp REG1w, #IS_CONST
2086-
| bne >2
2087-
| ldrsw REG1, OP:REG0->op2.constant
2088-
| add REG0, REG0, REG1
2089-
| b >3
2090-
|2:
2091-
| ldr REG0w, OP:REG0->op2.var
2092-
| add REG0, REG0, FP
2093-
|3:
2094-
| mov CARG1, #E_WARNING
2095-
| LOAD_ADDR CARG2, "Undefined array key \"%s\""
2096-
| ldr CARG3, [REG0]
2097-
| add CARG3, CARG3, #offsetof(zend_string, val)
2098-
#ifdef __APPLE__
2099-
| str CARG3, [sp, #-16]!
2100-
| EXT_CALL zend_error, REG0
2101-
| add sp, sp, #16
2102-
| ldp x29, x30, [sp], #16
2103-
| ret
2104-
#else
2105-
| EXT_JMP zend_error, REG0 // tail call
2106-
| //add r4, 8
2107-
| //ret
2108-
#endif
2046+
|| if (!GCC_GLOBAL_REGS) {
2047+
| mov FCARG1x, FP
2048+
|| }
2049+
| EXT_JMP zend_jit_undefined_string_key, REG0
21092050

21102051
return 1;
21112052
}

ext/opcache/jit/zend_jit_disasm.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,8 @@ static int zend_jit_disasm_init(void)
655655
REGISTER_HELPER(zend_jit_vm_stack_free_args_helper);
656656
REGISTER_HELPER(zend_jit_copy_extra_args_helper);
657657
REGISTER_HELPER(zend_jit_deprecated_helper);
658+
REGISTER_HELPER(zend_jit_undefined_long_key);
659+
REGISTER_HELPER(zend_jit_undefined_string_key);
658660
REGISTER_HELPER(zend_jit_assign_const_to_typed_ref);
659661
REGISTER_HELPER(zend_jit_assign_tmp_to_typed_ref);
660662
REGISTER_HELPER(zend_jit_assign_var_to_typed_ref);

ext/opcache/jit/zend_jit_internal.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,8 @@ ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL zend_jit_loop_counter_helper(ZEND_OPCODE_H
328328

329329
void ZEND_FASTCALL zend_jit_copy_extra_args_helper(EXECUTE_DATA_D);
330330
bool ZEND_FASTCALL zend_jit_deprecated_helper(OPLINE_D);
331+
void ZEND_FASTCALL zend_jit_undefined_long_key(EXECUTE_DATA_D);
332+
void ZEND_FASTCALL zend_jit_undefined_string_key(EXECUTE_DATA_D);
331333

332334
zend_constant* ZEND_FASTCALL zend_jit_get_constant(const zval *key, uint32_t flags);
333335
zend_constant* ZEND_FASTCALL zend_jit_check_constant(const zval *key);

ext/opcache/jit/zend_jit_vm_helpers.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,43 @@ bool ZEND_FASTCALL zend_jit_deprecated_helper(OPLINE_D)
199199
return 1;
200200
}
201201

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

ext/opcache/jit/zend_jit_x86.dasc

Lines changed: 8 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -1966,50 +1966,10 @@ static int zend_jit_undefined_offset_ex_stub(dasm_State **Dst)
19661966
static int zend_jit_undefined_offset_stub(dasm_State **Dst)
19671967
{
19681968
|->undefined_offset:
1969-
|.if X64WIN
1970-
| sub r4, 0x28
1971-
|.elif X64
1972-
| sub r4, 8
1973-
|.else
1974-
| sub r4, 12
1975-
|.endif
1976-
| mov r0, EX->opline
1977-
| mov ecx, dword OP:r0->result.var
1978-
| cmp byte OP:r0->op2_type, IS_CONST
1979-
| SET_Z_TYPE_INFO FP + r1, IS_NULL
1980-
| jne >2
1981-
|.if X64
1982-
| movsxd r1, dword OP:r0->op2.constant
1983-
| add r0, r1
1984-
|.else
1985-
| mov r0, aword OP:r0->op2.zv
1986-
|.endif
1987-
| jmp >3
1988-
|2:
1989-
| mov eax, dword OP:r0->op2.var
1990-
| add r0, FP
1991-
|3:
1992-
|.if X64WIN
1993-
| mov CARG1, E_WARNING
1994-
| LOAD_ADDR CARG2, "Undefined array key " ZEND_LONG_FMT
1995-
| mov CARG3, aword [r0]
1996-
| EXT_CALL zend_error, r0
1997-
| add r4, 0x28 // stack alignment
1998-
|.elif X64
1999-
| mov CARG1, E_WARNING
2000-
| LOAD_ADDR CARG2, "Undefined array key " ZEND_LONG_FMT
2001-
| mov CARG3, aword [r0]
2002-
| EXT_CALL zend_error, r0
2003-
| add r4, 8 // stack alignment
2004-
|.else
2005-
| sub r4, 4
2006-
| push aword [r0]
2007-
| push "Undefined array key " ZEND_LONG_FMT
2008-
| push E_WARNING
2009-
| EXT_CALL zend_error, r0
2010-
| add r4, 28
2011-
|.endif
2012-
| ret
1969+
|| if (!GCC_GLOBAL_REGS) {
1970+
| mov FCARG1a, FP
1971+
|| }
1972+
| EXT_JMP zend_jit_undefined_long_key, r0
20131973

20141974
return 1;
20151975
}
@@ -2026,54 +1986,10 @@ static int zend_jit_undefined_index_ex_stub(dasm_State **Dst)
20261986
static int zend_jit_undefined_index_stub(dasm_State **Dst)
20271987
{
20281988
|->undefined_index:
2029-
|.if X64WIN
2030-
| sub r4, 0x28
2031-
|.elif X64
2032-
| sub r4, 8
2033-
|.else
2034-
| sub r4, 12
2035-
|.endif
2036-
| mov r0, EX->opline
2037-
| mov ecx, dword OP:r0->result.var
2038-
| cmp byte OP:r0->op2_type, IS_CONST
2039-
| SET_Z_TYPE_INFO FP + r1, IS_NULL
2040-
| jne >2
2041-
|.if X64
2042-
| movsxd r1, dword OP:r0->op2.constant
2043-
| add r0, r1
2044-
|.else
2045-
| mov r0, aword OP:r0->op2.zv
2046-
|.endif
2047-
| jmp >3
2048-
|2:
2049-
| mov eax, dword OP:r0->op2.var
2050-
| add r0, FP
2051-
|3:
2052-
|.if X64WIN
2053-
| mov CARG1, E_WARNING
2054-
| LOAD_ADDR CARG2, "Undefined array key \"%s\""
2055-
| mov CARG3, aword [r0]
2056-
| add CARG3, offsetof(zend_string, val)
2057-
| EXT_CALL zend_error, r0
2058-
| add r4, 0x28
2059-
|.elif X64
2060-
| mov CARG1, E_WARNING
2061-
| LOAD_ADDR CARG2, "Undefined array key \"%s\""
2062-
| mov CARG3, aword [r0]
2063-
| add CARG3, offsetof(zend_string, val)
2064-
| EXT_CALL zend_error, r0
2065-
| add r4, 8
2066-
|.else
2067-
| sub r4, 4
2068-
| mov r0, aword [r0]
2069-
| add r0, offsetof(zend_string, val)
2070-
| push r0
2071-
| push "Undefined array key \"%s\""
2072-
| push E_WARNING
2073-
| EXT_CALL zend_error, r0
2074-
| add r4, 28
2075-
|.endif
2076-
| ret
1989+
|| if (!GCC_GLOBAL_REGS) {
1990+
| mov FCARG1a, FP
1991+
|| }
1992+
| EXT_JMP zend_jit_undefined_string_key, r0
20771993

20781994
return 1;
20791995
}

ext/opcache/tests/jit/gh12812.phpt

Lines changed: 29 additions & 0 deletions
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)