Skip to content

Commit ab99072

Browse files
committed
Merge branch 'PHP-8.2'
* PHP-8.2: Fix segfault when using ReflectionFiber (fixes php#10439)
2 parents 5c84e0a + f1818d7 commit ab99072

File tree

6 files changed

+115
-7
lines changed

6 files changed

+115
-7
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ PHP NEWS
100100
method). (ilutov)
101101
. Fix GH-10259 (ReflectionClass::getStaticProperties doesn't need null return
102102
type). (kocsismate)
103+
. Fix Segfault when using ReflectionFiber suspended by an internal function.
104+
(danog)
103105

104106
- Sockets:
105107
. Added SO_ATTACH_REUSEPORT_CBPF socket option, to give tighter control

ext/reflection/php_reflection.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7041,7 +7041,13 @@ ZEND_METHOD(ReflectionFiber, getExecutingLine)
70417041
prev_execute_data = fiber->execute_data->prev_execute_data;
70427042
}
70437043

7044-
RETURN_LONG(prev_execute_data->opline->lineno);
7044+
while (prev_execute_data && (!prev_execute_data->func || !ZEND_USER_CODE(prev_execute_data->func->common.type))) {
7045+
prev_execute_data = prev_execute_data->prev_execute_data;
7046+
}
7047+
if (prev_execute_data && prev_execute_data->func && ZEND_USER_CODE(prev_execute_data->func->common.type)) {
7048+
RETURN_LONG(prev_execute_data->opline->lineno);
7049+
}
7050+
RETURN_NULL();
70457051
}
70467052

70477053
ZEND_METHOD(ReflectionFiber, getExecutingFile)
@@ -7059,7 +7065,13 @@ ZEND_METHOD(ReflectionFiber, getExecutingFile)
70597065
prev_execute_data = fiber->execute_data->prev_execute_data;
70607066
}
70617067

7062-
RETURN_STR_COPY(prev_execute_data->func->op_array.filename);
7068+
while (prev_execute_data && (!prev_execute_data->func || !ZEND_USER_CODE(prev_execute_data->func->common.type))) {
7069+
prev_execute_data = prev_execute_data->prev_execute_data;
7070+
}
7071+
if (prev_execute_data && prev_execute_data->func && ZEND_USER_CODE(prev_execute_data->func->common.type)) {
7072+
RETURN_STR_COPY(prev_execute_data->func->op_array.filename);
7073+
}
7074+
RETURN_NULL();
70637075
}
70647076

70657077
ZEND_METHOD(ReflectionFiber, getCallable)

ext/reflection/php_reflection.stub.php

Lines changed: 2 additions & 2 deletions
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

Lines changed: 5 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 31 additions & 0 deletions
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+
}
Lines changed: 61 additions & 0 deletions
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)