Merge branch 'PHP-8.1' into PHP-8.2

This commit is contained in:
Derick Rethans 2022-12-23 16:36:40 +00:00
commit 9529b8919f
4 changed files with 138 additions and 6 deletions

20
Zend/tests/gh10072-2.phpt Normal file
View file

@ -0,0 +1,20 @@
--TEST--
GH-10072 (PHP crashes when execute_ex is overridden and a trampoline is used from internal code during shutdown)
--EXTENSIONS--
zend_test
--INI--
zend_test.replace_zend_execute_ex=1
opcache.jit=disable
--FILE--
<?php
class TrampolineTest {
public function __call(string $name, array $arguments) {
echo 'Trampoline for ', $name, PHP_EOL;
}
}
register_shutdown_function([new TrampolineTest(), 'shutdown']);
?>
--EXPECT--
Trampoline for shutdown

106
Zend/tests/gh10072.phpt Normal file
View file

@ -0,0 +1,106 @@
--TEST--
GH-10072 (PHP crashes when execute_ex is overridden and a trampoline is used from internal code)
--EXTENSIONS--
zend_test
--INI--
zend_test.replace_zend_execute_ex=1
opcache.jit=disable
--FILE--
<?php
class DummyStreamWrapper
{
/** @var resource|null */
public $context;
/** @var resource|null */
public $handle;
public function stream_cast(int $castAs)
{
return $this->handle;
}
public function stream_close(): void
{
}
public function stream_open(string $path, string $mode, int $options = 0, ?string &$openedPath = null): bool
{
return true;
}
public function stream_read(int $count)
{
return 0;
}
public function stream_seek(int $offset, int $whence = SEEK_SET): bool
{
return true;
}
public function stream_set_option(int $option, int $arg1, ?int $arg2): bool
{
return false;
}
public function stream_stat()
{
return [];
}
public function stream_tell()
{
return [];
}
public function stream_truncate(int $newSize): bool
{
return true;
}
public function stream_write(string $data)
{
}
public function unlink(string $path): bool
{
return false;
}
}
class TrampolineTest {
/** @var resource|null */
public $context;
/** @var object|null */
private $wrapper;
public function __call(string $name, array $arguments) {
if (!$this->wrapper) {
$this->wrapper = new DummyStreamWrapper();
}
echo 'Trampoline for ', $name, PHP_EOL;
return $this->wrapper->$name(...$arguments);
}
}
stream_wrapper_register('custom', TrampolineTest::class);
$fp = fopen("custom://myvar", "r+");
?>
--EXPECT--
Trampoline for stream_open
Trampoline for stream_close

View file

@ -8723,7 +8723,9 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY, SPEC(OBSERVER))
SAVE_OPLINE_EX();
ZEND_OBSERVER_FCALL_BEGIN(execute_data);
execute_data = EX(prev_execute_data);
LOAD_OPLINE();
if (execute_data) {
LOAD_OPLINE();
}
ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
zend_execute_ex(call);
}
@ -8775,7 +8777,7 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY, SPEC(OBSERVER))
execute_data = EG(current_execute_data);
if (!EX(func) || !ZEND_USER_CODE(EX(func)->type) || (call_info & ZEND_CALL_TOP)) {
if (!execute_data || !EX(func) || !ZEND_USER_CODE(EX(func)->type) || (call_info & ZEND_CALL_TOP)) {
ZEND_VM_RETURN();
}

12
Zend/zend_vm_execute.h generated
View file

@ -3409,7 +3409,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
SAVE_OPLINE_EX();
execute_data = EX(prev_execute_data);
LOAD_OPLINE();
if (execute_data) {
LOAD_OPLINE();
}
ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
zend_execute_ex(call);
}
@ -3460,7 +3462,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_HANDLER(Z
execute_data = EG(current_execute_data);
if (!EX(func) || !ZEND_USER_CODE(EX(func)->type) || (call_info & ZEND_CALL_TOP)) {
if (!execute_data || !EX(func) || !ZEND_USER_CODE(EX(func)->type) || (call_info & ZEND_CALL_TOP)) {
ZEND_VM_RETURN();
}
@ -3547,7 +3549,9 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_
SAVE_OPLINE_EX();
zend_observer_fcall_begin(execute_data);
execute_data = EX(prev_execute_data);
LOAD_OPLINE();
if (execute_data) {
LOAD_OPLINE();
}
ZEND_ADD_CALL_FLAG(call, ZEND_CALL_TOP);
zend_execute_ex(call);
}
@ -3599,7 +3603,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CALL_TRAMPOLINE_SPEC_OBSERVER_
execute_data = EG(current_execute_data);
if (!EX(func) || !ZEND_USER_CODE(EX(func)->type) || (call_info & ZEND_CALL_TOP)) {
if (!execute_data || !EX(func) || !ZEND_USER_CODE(EX(func)->type) || (call_info & ZEND_CALL_TOP)) {
ZEND_VM_RETURN();
}