Skip to content

Commit b24cc73

Browse files
committed
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3: Fixed GH-16233: Observer segfault when calling user function in internal function via trampoline
2 parents befe404 + 0338008 commit b24cc73

File tree

6 files changed

+84
-2
lines changed

6 files changed

+84
-2
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ PHP NEWS
3535
. Fixed bug GH-15866 (Core dumped in Zend/zend_generators.c). (Arnaud)
3636
. Fixed bug GH-15960 (Foreach edge cases with lazy objects). (Arnaud)
3737
. Fixed bug GH-16188 (Assertion failure in Zend/zend_exceptions.c). (Arnaud)
38+
. Fixed bug GH-16233 (Observer segfault when calling user function in
39+
internal function via trampoline). (nielsdos)
3840

3941
- DOM:
4042
. Fixed bug GH-16039 (Segmentation fault (access null pointer) in

Zend/zend_object_handlers.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "zend_compile.h"
3333
#include "zend_hash.h"
3434
#include "zend_property_hooks.h"
35+
#include "zend_observer.h"
3536

3637
#define DEBUG_OBJECT_HANDLERS 0
3738

@@ -1627,7 +1628,8 @@ ZEND_API zend_function *zend_get_call_trampoline_func(const zend_class_entry *ce
16271628
* value so that it doesn't contain garbage when the engine allocates space for the next stack
16281629
* frame. This didn't cause any issues until now due to "lucky" structure layout. */
16291630
func->last_var = 0;
1630-
func->T = (fbc->type == ZEND_USER_FUNCTION)? MAX(fbc->op_array.last_var + fbc->op_array.T, 2) : 2;
1631+
uint32_t min_T = 2 + ZEND_OBSERVER_ENABLED;
1632+
func->T = (fbc->type == ZEND_USER_FUNCTION)? MAX(fbc->op_array.last_var + fbc->op_array.T, min_T) : min_T;
16311633
func->filename = (fbc->type == ZEND_USER_FUNCTION)? fbc->op_array.filename : ZSTR_EMPTY_ALLOC();
16321634
func->line_start = (fbc->type == ZEND_USER_FUNCTION)? fbc->op_array.line_start : 0;
16331635
func->line_end = (fbc->type == ZEND_USER_FUNCTION)? fbc->op_array.line_end : 0;

ext/zend_test/test.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,6 +1091,23 @@ static ZEND_METHOD(_ZendTestMagicCall, __call)
10911091
RETURN_ARR(zend_new_pair(&name_zv, arguments));
10921092
}
10931093

1094+
static ZEND_METHOD(_ZendTestMagicCallForward, __call)
1095+
{
1096+
zend_string *name;
1097+
zval *arguments;
1098+
1099+
ZEND_PARSE_PARAMETERS_START(2, 2)
1100+
Z_PARAM_STR(name)
1101+
Z_PARAM_ARRAY(arguments)
1102+
ZEND_PARSE_PARAMETERS_END();
1103+
1104+
ZEND_IGNORE_VALUE(arguments);
1105+
1106+
zval func;
1107+
ZVAL_STR(&func, name);
1108+
call_user_function(NULL, NULL, &func, return_value, 0, NULL);
1109+
}
1110+
10941111
PHP_INI_BEGIN()
10951112
STD_PHP_INI_BOOLEAN("zend_test.replace_zend_execute_ex", "0", PHP_INI_SYSTEM, OnUpdateBool, replace_zend_execute_ex, zend_zend_test_globals, zend_test_globals)
10961113
STD_PHP_INI_BOOLEAN("zend_test.register_passes", "0", PHP_INI_SYSTEM, OnUpdateBool, register_passes, zend_zend_test_globals, zend_test_globals)
@@ -1280,6 +1297,8 @@ PHP_MINIT_FUNCTION(zend_test)
12801297

12811298
zend_test_magic_call = register_class__ZendTestMagicCall();
12821299

1300+
register_class__ZendTestMagicCallForward();
1301+
12831302
zend_register_functions(NULL, ext_function_legacy, NULL, EG(current_module)->type);
12841303

12851304
// Loading via dl() not supported with the observer API

ext/zend_test/test.stub.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,11 @@ class _ZendTestMagicCall
7575
public function __call(string $name, array $args): mixed {}
7676
}
7777

78+
class _ZendTestMagicCallForward
79+
{
80+
public function __call(string $name, array $args): mixed {}
81+
}
82+
7883
class _ZendTestChildClass extends _ZendTestClass
7984
{
8085
public function returnsThrowable(): Exception {}

ext/zend_test/test_arginfo.h

Lines changed: 23 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/zend_test/tests/gh16233.phpt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
GH-16233 (Observer segfault when calling user function in internal function via trampoline)
3+
--EXTENSIONS--
4+
zend_test
5+
--INI--
6+
zend_test.observer.enabled=1
7+
zend_test.observer.show_output=1
8+
zend_test.observer.observe_all=1
9+
--FILE--
10+
<?php
11+
12+
function callee() {
13+
echo "in callee\n";
14+
}
15+
16+
$test = new _ZendTestMagicCallForward;
17+
$test->callee();
18+
echo "done\n";
19+
20+
?>
21+
--EXPECTF--
22+
<!-- init '%sgh16233.php' -->
23+
<file '%sgh16233.php'>
24+
<!-- init _ZendTestMagicCallForward::__call() -->
25+
<_ZendTestMagicCallForward::__call>
26+
<!-- init callee() -->
27+
<callee>
28+
in callee
29+
</callee>
30+
</_ZendTestMagicCallForward::__call>
31+
done
32+
</file '%sgh16233.php'>

0 commit comments

Comments
 (0)