Skip to content

Commit 1879ec1

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-17577: JIT packed type guard crash
2 parents 9b7e086 + 78da288 commit 1879ec1

File tree

2 files changed

+41
-6
lines changed

2 files changed

+41
-6
lines changed

ext/opcache/jit/zend_jit_trace.c

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1872,7 +1872,8 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
18721872
if (!(orig_op1_type & IS_TRACE_PACKED)) {
18731873
zend_ssa_var_info *info = &tssa->var_info[tssa->ops[idx].op1_use];
18741874

1875-
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)) {
1875+
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)
1876+
&& (info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
18761877
info->type |= MAY_BE_PACKED_GUARD;
18771878
info->type &= ~MAY_BE_ARRAY_PACKED;
18781879
}
@@ -1881,7 +1882,8 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
18811882
&& val_type != IS_UNDEF) {
18821883
zend_ssa_var_info *info = &tssa->var_info[tssa->ops[idx].op1_use];
18831884

1884-
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)) {
1885+
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)
1886+
&& (info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
18851887
info->type |= MAY_BE_PACKED_GUARD;
18861888
info->type &= ~(MAY_BE_ARRAY_NUMERIC_HASH|MAY_BE_ARRAY_STRING_HASH);
18871889
}
@@ -1965,7 +1967,8 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
19651967

19661968
zend_ssa_var_info *info = &tssa->var_info[tssa->ops[idx].op1_use];
19671969

1968-
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)) {
1970+
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)
1971+
&& (info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
19691972
info->type |= MAY_BE_PACKED_GUARD;
19701973
if (orig_op1_type & IS_TRACE_PACKED) {
19711974
info->type &= ~(MAY_BE_ARRAY_NUMERIC_HASH|MAY_BE_ARRAY_STRING_HASH);
@@ -2067,7 +2070,8 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
20672070

20682071
zend_ssa_var_info *info = &tssa->var_info[tssa->ops[idx].op1_use];
20692072

2070-
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)) {
2073+
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)
2074+
&& (info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
20712075
info->type |= MAY_BE_PACKED_GUARD;
20722076
if (orig_op1_type & IS_TRACE_PACKED) {
20732077
info->type &= ~(MAY_BE_ARRAY_NUMERIC_HASH|MAY_BE_ARRAY_STRING_HASH);
@@ -2097,7 +2101,8 @@ static zend_ssa *zend_jit_trace_build_tssa(zend_jit_trace_rec *trace_buffer, uin
20972101

20982102
zend_ssa_var_info *info = &tssa->var_info[tssa->ops[idx].op1_use];
20992103

2100-
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)) {
2104+
if (MAY_BE_PACKED(info->type) && MAY_BE_HASH(info->type)
2105+
&& (info->type & (MAY_BE_ANY|MAY_BE_UNDEF)) == MAY_BE_ARRAY) {
21012106
info->type |= MAY_BE_PACKED_GUARD;
21022107
info->type &= ~MAY_BE_ARRAY_PACKED;
21032108
}
@@ -4236,10 +4241,13 @@ static const void *zend_jit_trace(zend_jit_trace_rec *trace_buffer, uint32_t par
42364241
if ((info & MAY_BE_PACKED_GUARD) != 0
42374242
&& (trace_buffer->stop == ZEND_JIT_TRACE_STOP_LOOP
42384243
|| trace_buffer->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_CALL
4239-
|| trace_buffer->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET)
4244+
|| (trace_buffer->stop == ZEND_JIT_TRACE_STOP_RECURSIVE_RET
4245+
&& EX_VAR_TO_NUM((opline-1)->result.var) == i))
42404246
&& (ssa->vars[i].use_chain != -1
42414247
|| (ssa->vars[i].phi_use_chain
42424248
&& !(ssa->var_info[ssa->vars[i].phi_use_chain->ssa_var].type & MAY_BE_PACKED_GUARD)))) {
4249+
ZEND_ASSERT(STACK_TYPE(stack, i) == IS_ARRAY);
4250+
42434251
if (!zend_jit_packed_guard(&ctx, opline, EX_NUM_TO_VAR(i), info)) {
42444252
goto jit_failure;
42454253
}

ext/opcache/tests/jit/gh17577.phpt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
GH-17577 (JIT packed type guard crash)
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.jit_buffer_size=16M
7+
opcache.jit_hot_func=1
8+
--FILE--
9+
<?php
10+
$a = array(
11+
array(1,2,3),
12+
0,
13+
);
14+
function my_dump($var) {
15+
}
16+
foreach($a as $b) {
17+
for ($i = 0; $i < 3; $i++) {
18+
my_dump($b[$i]);
19+
}
20+
}
21+
?>
22+
--EXPECTF--
23+
Warning: Trying to access array offset on int in %s on line %d
24+
25+
Warning: Trying to access array offset on int in %s on line %d
26+
27+
Warning: Trying to access array offset on int in %s on line %d

0 commit comments

Comments
 (0)