1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Fix GH-17654: Multiple classes using same trait causes function JIT crash

This test has two classes that use the same trait. In function JIT mode
the same cache slot will be used. This causes problems because it is
primed for the first class and then reused for the second class,
resulting in an incorrect type check failure.

The current check for a megamorphic trait call requires current_frame to
not be NULL, but this is only set in tracing mode and not in function
mode.

This patch corrects the check.

Closes GH-17660.
This commit is contained in:
Niels Dossche
2025-01-31 21:41:45 +01:00
parent 76fccc2b02
commit f88445bdf8
4 changed files with 48 additions and 6 deletions

4
NEWS
View File

@@ -11,6 +11,10 @@ PHP NEWS
. Fixed bug GH-17618 (UnhandledMatchError does not take . Fixed bug GH-17618 (UnhandledMatchError does not take
zend.exception_ignore_args=1 into account). (timwolla) zend.exception_ignore_args=1 into account). (timwolla)
- Opcache:
. Fixed bug GH-17654 (Multiple classes using same trait causes function
JIT crash). (nielsdos)
- PHPDBG: - PHPDBG:
. Partially fixed bug GH-17387 (Trivial crash in phpdbg lexer). (nielsdos) . Partially fixed bug GH-17387 (Trivial crash in phpdbg lexer). (nielsdos)
. Fix memory leak in phpdbg calling registered function. (nielsdos) . Fix memory leak in phpdbg calling registered function. (nielsdos)

View File

@@ -9200,9 +9200,9 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
func = call_info->callee_func; func = call_info->callee_func;
} }
if ((op_array->fn_flags & ZEND_ACC_TRAIT_CLONE) if ((op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)
&& JIT_G(current_frame) && (!JIT_G(current_frame) ||
&& JIT_G(current_frame)->call !JIT_G(current_frame)->call ||
&& !JIT_G(current_frame)->call->func) { !JIT_G(current_frame)->call->func)) {
call_info = NULL; func = NULL; /* megamorphic call from trait */ call_info = NULL; func = NULL; /* megamorphic call from trait */
} }
} }

View File

@@ -9931,9 +9931,9 @@ static int zend_jit_do_fcall(dasm_State **Dst, const zend_op *opline, const zend
func = call_info->callee_func; func = call_info->callee_func;
} }
if ((op_array->fn_flags & ZEND_ACC_TRAIT_CLONE) if ((op_array->fn_flags & ZEND_ACC_TRAIT_CLONE)
&& JIT_G(current_frame) && (!JIT_G(current_frame) ||
&& JIT_G(current_frame)->call !JIT_G(current_frame)->call ||
&& !JIT_G(current_frame)->call->func) { !JIT_G(current_frame)->call->func)) {
call_info = NULL; func = NULL; /* megamorphic call from trait */ call_info = NULL; func = NULL; /* megamorphic call from trait */
} }
} }

View File

@@ -0,0 +1,38 @@
--TEST--
GH-17654 (Multiple classes using same trait causes function JIT crash)
--EXTENSIONS--
opcache
--INI--
opcache.jit=1214
opcache.jit_buffer_size=16M
--FILE--
<?php
trait TestTrait {
public function addUnit(string $x) {
self::addRawUnit($this, $x);
}
public function addRawUnit(self $data, string $x) {
var_dump($x);
}
}
class Test {
use TestTrait;
}
class Test2 {
use TestTrait;
}
function main()
{
(new Test2)->addUnit("test2");
(new Test)->addUnit("test");
}
main();
?>
--EXPECT--
string(5) "test2"
string(4) "test"