Skip to content

Commit f1818d7

Browse files
committed
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1: Fix segfault when using ReflectionFiber (fixes php#10439)
2 parents c891495 + 8d1c0a1 commit f1818d7

6 files changed

+115
-7
lines changed

NEWS

+2
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ PHP NEWS
6767
- Reflection:
6868
. Fixed bug GH-10623 (Reflection::getClosureUsedVariables opcode fix with
6969
variadic arguments). (nielsdos)
70+
. Fix Segfault when using ReflectionFiber suspended by an internal function.
71+
(danog)
7072

7173
- Session:
7274
. Fixed ps_files_cleanup_dir() on failure code paths with -1 instead of 0 as

ext/reflection/php_reflection.c

+14-2
Original file line numberDiff line numberDiff line change
@@ -7085,7 +7085,13 @@ ZEND_METHOD(ReflectionFiber, getExecutingLine)
70857085
prev_execute_data = fiber->execute_data->prev_execute_data;
70867086
}
70877087

7088-
RETURN_LONG(prev_execute_data->opline->lineno);
7088+
while (prev_execute_data && (!prev_execute_data->func || !ZEND_USER_CODE(prev_execute_data->func->common.type))) {
7089+
prev_execute_data = prev_execute_data->prev_execute_data;
7090+
}
7091+
if (prev_execute_data && prev_execute_data->func && ZEND_USER_CODE(prev_execute_data->func->common.type)) {
7092+
RETURN_LONG(prev_execute_data->opline->lineno);
7093+
}
7094+
RETURN_NULL();
70897095
}
70907096

70917097
ZEND_METHOD(ReflectionFiber, getExecutingFile)
@@ -7103,7 +7109,13 @@ ZEND_METHOD(ReflectionFiber, getExecutingFile)
71037109
prev_execute_data = fiber->execute_data->prev_execute_data;
71047110
}
71057111

7106-
RETURN_STR_COPY(prev_execute_data->func->op_array.filename);
7112+
while (prev_execute_data && (!prev_execute_data->func || !ZEND_USER_CODE(prev_execute_data->func->common.type))) {
7113+
prev_execute_data = prev_execute_data->prev_execute_data;
7114+
}
7115+
if (prev_execute_data && prev_execute_data->func && ZEND_USER_CODE(prev_execute_data->func->common.type)) {
7116+
RETURN_STR_COPY(prev_execute_data->func->op_array.filename);
7117+
}
7118+
RETURN_NULL();
71077119
}
71087120

71097121
ZEND_METHOD(ReflectionFiber, getCallable)

ext/reflection/php_reflection.stub.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -874,9 +874,9 @@ public function __construct(Fiber $fiber) {}
874874

875875
public function getFiber(): Fiber {}
876876

877-
public function getExecutingFile(): string {}
877+
public function getExecutingFile(): ?string {}
878878

879-
public function getExecutingLine(): int {}
879+
public function getExecutingLine(): ?int {}
880880

881881
public function getCallable(): callable {}
882882

ext/reflection/php_reflection_arginfo.h

+5-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
--TEST--
2+
ReflectionFiber should not segfault when inspecting fibers with no stack frames before suspend
3+
--FILE--
4+
<?php
5+
$f = new Fiber(Fiber::suspend(...));
6+
$f->start();
7+
8+
$reflection = new ReflectionFiber($f);
9+
10+
var_dump($reflection->getExecutingFile());
11+
var_dump($reflection->getExecutingLine());
12+
var_dump($reflection->getTrace());
13+
14+
?>
15+
--EXPECTF--
16+
NULL
17+
NULL
18+
array(1) {
19+
[0]=>
20+
array(4) {
21+
["function"]=>
22+
string(7) "suspend"
23+
["class"]=>
24+
string(5) "Fiber"
25+
["type"]=>
26+
string(2) "::"
27+
["args"]=>
28+
array(0) {
29+
}
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
--TEST--
2+
ReflectionFiber should not segfault when inspecting fibers where the previous stack frame is a native function
3+
--FILE--
4+
<?php
5+
6+
namespace test;
7+
8+
$f = new \Fiber(fn() => call_user_func(["Fiber", "suspend"]));
9+
$f->start();
10+
11+
$reflection = new \ReflectionFiber($f);
12+
13+
var_dump($reflection->getExecutingFile());
14+
var_dump($reflection->getExecutingLine());
15+
var_dump($reflection->getTrace());
16+
17+
?>
18+
--EXPECTF--
19+
string(%d) "%sReflectionFiber_notrace_2.php"
20+
int(5)
21+
array(3) {
22+
[0]=>
23+
array(4) {
24+
["function"]=>
25+
string(7) "suspend"
26+
["class"]=>
27+
string(5) "Fiber"
28+
["type"]=>
29+
string(2) "::"
30+
["args"]=>
31+
array(0) {
32+
}
33+
}
34+
[1]=>
35+
array(4) {
36+
["file"]=>
37+
string(%d) "%sReflectionFiber_notrace_2.php"
38+
["line"]=>
39+
int(5)
40+
["function"]=>
41+
string(14) "call_user_func"
42+
["args"]=>
43+
array(1) {
44+
[0]=>
45+
array(2) {
46+
[0]=>
47+
string(5) "Fiber"
48+
[1]=>
49+
string(7) "suspend"
50+
}
51+
}
52+
}
53+
[2]=>
54+
array(2) {
55+
["function"]=>
56+
string(14) "test\{closure}"
57+
["args"]=>
58+
array(0) {
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)