Skip to content

Commit 4011657

Browse files
committed
Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0: [ci skip] NEWS Fix generator memory leaks when interrupted during argument evaluation (#9756)
2 parents 35167af + 1d67e34 commit 4011657

14 files changed

+536
-2
lines changed

Zend/tests/generators/gh9750-001.phpt

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Bug GH-9750 001 (Generator memory leak when interrupted during argument evaluation)
3+
--FILE--
4+
<?php
5+
6+
function f() {
7+
}
8+
9+
class C {
10+
function __destruct() {
11+
echo __METHOD__, "\n";
12+
}
13+
}
14+
15+
$gen = function ($c) use (&$gen) {
16+
f($gen, yield);
17+
};
18+
19+
$gen = $gen(new C());
20+
21+
foreach ($gen as $value) {
22+
break;
23+
}
24+
25+
$gen = null;
26+
27+
gc_collect_cycles();
28+
29+
?>
30+
==DONE==
31+
--EXPECT--
32+
C::__destruct
33+
==DONE==

Zend/tests/generators/gh9750-002.phpt

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Bug GH-9750 002 (Generator memory leak when interrupted during argument evaluation)
3+
--FILE--
4+
<?php
5+
6+
function f() {
7+
}
8+
9+
class C {
10+
function __destruct() {
11+
echo __METHOD__, "\n";
12+
}
13+
}
14+
15+
$gen = function ($c) use (&$gen) {
16+
f($gen, f(yield));
17+
};
18+
19+
$gen = $gen(new C());
20+
21+
foreach ($gen as $value) {
22+
break;
23+
}
24+
25+
$gen = null;
26+
27+
gc_collect_cycles();
28+
29+
?>
30+
==DONE==
31+
--EXPECT--
32+
C::__destruct
33+
==DONE==

Zend/tests/generators/gh9750-003.phpt

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Bug GH-9750 003 (Generator memory leak when interrupted during argument evaluation)
3+
--FILE--
4+
<?php
5+
6+
function f() {
7+
}
8+
9+
class C {
10+
function __destruct() {
11+
echo __METHOD__, "\n";
12+
}
13+
}
14+
15+
$gen = function ($c) use (&$gen) {
16+
f(f($gen, yield));
17+
};
18+
19+
$gen = $gen(new C());
20+
21+
foreach ($gen as $value) {
22+
break;
23+
}
24+
25+
$gen = null;
26+
27+
gc_collect_cycles();
28+
29+
?>
30+
==DONE==
31+
--EXPECT--
32+
C::__destruct
33+
==DONE==

Zend/tests/generators/gh9750-004.phpt

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Bug GH-9750 004 (Generator memory leak when interrupted during argument evaluation)
3+
--FILE--
4+
<?php
5+
6+
function f() {
7+
}
8+
9+
class C {
10+
function __destruct() {
11+
echo __METHOD__, "\n";
12+
}
13+
}
14+
15+
$gen = function ($c) use (&$gen) {
16+
f(new stdClass, $gen, yield);
17+
};
18+
19+
$gen = $gen(new C());
20+
21+
foreach ($gen as $value) {
22+
break;
23+
}
24+
25+
$gen = null;
26+
27+
gc_collect_cycles();
28+
29+
?>
30+
==DONE==
31+
--EXPECT--
32+
C::__destruct
33+
==DONE==

Zend/tests/generators/gh9750-005.phpt

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
--TEST--
2+
Bug GH-9750 002 (Generator memory leak when interrupted during argument evaluation)
3+
--FILE--
4+
<?php
5+
6+
function f(...$x) {
7+
}
8+
9+
class C {
10+
function __destruct() {
11+
echo __METHOD__, "\n";
12+
}
13+
}
14+
15+
$gen = function ($c) use (&$gen) {
16+
f(b: $gen, c: yield);
17+
};
18+
19+
$gen = $gen(new C());
20+
21+
foreach ($gen as $value) {
22+
break;
23+
}
24+
25+
$gen = null;
26+
$c = null;
27+
28+
gc_collect_cycles();
29+
30+
?>
31+
==DONE==
32+
--EXPECT--
33+
C::__destruct
34+
==DONE==

Zend/tests/generators/gh9750-006.phpt

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Bug GH-9750 006 (Generator memory leak when interrupted during argument evaluation)
3+
--FILE--
4+
<?php
5+
6+
function f(...$x) {
7+
}
8+
9+
class C {
10+
function __destruct() {
11+
echo __METHOD__, "\n";
12+
}
13+
}
14+
15+
$gen = function ($c) use (&$gen) {
16+
f(a: $gen, b: f(c: yield));
17+
};
18+
19+
$gen = $gen(new C());
20+
21+
foreach ($gen as $value) {
22+
break;
23+
}
24+
25+
$gen = null;
26+
27+
gc_collect_cycles();
28+
29+
?>
30+
==DONE==
31+
--EXPECT--
32+
C::__destruct
33+
==DONE==

Zend/tests/generators/gh9750-007.phpt

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Bug GH-9750 007 (Generator memory leak when interrupted during argument evaluation)
3+
--FILE--
4+
<?php
5+
6+
function f(...$x) {
7+
}
8+
9+
class C {
10+
function __destruct() {
11+
echo __METHOD__, "\n";
12+
}
13+
}
14+
15+
$gen = function ($c) use (&$gen) {
16+
f(f(a: $gen, b: yield));
17+
};
18+
19+
$gen = $gen(new C());
20+
21+
foreach ($gen as $value) {
22+
break;
23+
}
24+
25+
$gen = null;
26+
27+
gc_collect_cycles();
28+
29+
?>
30+
==DONE==
31+
--EXPECT--
32+
C::__destruct
33+
==DONE==

Zend/tests/generators/gh9750-008.phpt

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
--TEST--
2+
Bug GH-9750 008 (Generator memory leak when interrupted during argument evaluation)
3+
--SKIPIF--
4+
<?php
5+
if (version_compare(PHP_VERSION, '8.1', '<')) { die('skip Broken on PHP < 8.1'); }
6+
?>
7+
--FILE--
8+
<?php
9+
10+
class C {
11+
function __destruct() {
12+
echo __METHOD__, "\n";
13+
}
14+
}
15+
16+
class D {
17+
function __destruct() {
18+
echo __METHOD__, "\n";
19+
}
20+
}
21+
22+
$gen = function ($c) use (&$gen) {
23+
new D($gen, yield);
24+
};
25+
26+
$gen = $gen(new C());
27+
28+
foreach ($gen as $value) {
29+
break;
30+
}
31+
32+
$gen = null;
33+
34+
gc_collect_cycles();
35+
36+
?>
37+
==DONE==
38+
--EXPECT--
39+
C::__destruct
40+
==DONE==

Zend/tests/generators/gh9750-009.phpt

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
--TEST--
2+
Bug GH-9750 009 (Generator memory leak when interrupted during argument evaluation)
3+
--FILE--
4+
<?php
5+
6+
function f() {
7+
}
8+
9+
class C {
10+
public function __construct(public mixed $x) {
11+
}
12+
public function __invoke() {
13+
}
14+
public function __destruct() {
15+
echo __METHOD__, "\n";
16+
}
17+
}
18+
19+
$gen = function () use (&$gen) {
20+
(new C($gen))(yield);
21+
};
22+
23+
$gen = $gen();
24+
25+
foreach ($gen as $value) {
26+
break;
27+
}
28+
29+
$gen = null;
30+
31+
gc_collect_cycles();
32+
33+
?>
34+
==DONE==
35+
--EXPECT--
36+
C::__destruct
37+
==DONE==

Zend/tests/generators/gh9750-010.phpt

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
Bug GH-9750 010 (Generator memory leak when interrupted during argument evaluation)
3+
--FILE--
4+
<?php
5+
6+
function f() {
7+
}
8+
9+
class C {
10+
function __destruct() {
11+
echo __METHOD__, "\n";
12+
}
13+
}
14+
15+
$gen = function ($c) use (&$gen) {
16+
$gen->valid(yield);
17+
};
18+
19+
$gen = $gen(new C());
20+
21+
foreach ($gen as $value) {
22+
break;
23+
}
24+
25+
$gen = null;
26+
27+
gc_collect_cycles();
28+
29+
?>
30+
==DONE==
31+
--EXPECT--
32+
C::__destruct
33+
==DONE==

Zend/tests/generators/gh9750-011.phpt

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
Bug GH-9750 011 (Generator memory leak when interrupted during argument evaluation)
3+
--FILE--
4+
<?php
5+
6+
function f() {
7+
}
8+
9+
class C {
10+
function getClosure() {
11+
return function () {
12+
return $this;
13+
};
14+
}
15+
function __destruct() {
16+
echo __METHOD__, "\n";
17+
}
18+
}
19+
20+
$gen = function ($c) use (&$gen) {
21+
$c($gen, yield);
22+
};
23+
24+
$gen = $gen((new C())->getClosure());
25+
26+
foreach ($gen as $value) {
27+
break;
28+
}
29+
30+
$gen = null;
31+
32+
gc_collect_cycles();
33+
34+
?>
35+
==DONE==
36+
--EXPECT--
37+
C::__destruct
38+
==DONE==

0 commit comments

Comments
 (0)