Skip to content

Commit 71ff104

Browse files
committed
Add test
1 parent 42d5158 commit 71ff104

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
--TEST--
2+
GH-14506 (Closing a userspace stream inside a userspace handler causes heap corruption)
3+
--FILE--
4+
<?php
5+
6+
class Bomb {
7+
8+
public $context;
9+
10+
function stream_open($path, $mode, $options, &$opened_path): bool
11+
{
12+
return true;
13+
}
14+
15+
function stream_write(string $data): int
16+
{
17+
global $readStream;
18+
fclose($readStream);
19+
return 0;
20+
}
21+
22+
function stream_read(int $count): false|string|null
23+
{
24+
global $readStream;
25+
fclose($readStream);
26+
return "";
27+
}
28+
29+
function stream_eof(): bool
30+
{
31+
global $readStream;
32+
fclose($readStream);
33+
return false;
34+
}
35+
36+
function stream_seek(int $offset, int $whence): bool
37+
{
38+
global $readStream;
39+
fclose($readStream);
40+
return false;
41+
}
42+
43+
function stream_cast(int $as)
44+
{
45+
global $readStream;
46+
fclose($readStream);
47+
return false;
48+
}
49+
50+
function stream_flush(): bool
51+
{
52+
global $readStream;
53+
fclose($readStream);
54+
return false;
55+
}
56+
}
57+
58+
stream_register_wrapper('bomb', Bomb::class);
59+
$readStream = fopen('bomb://1', 'r');
60+
fread($readStream, 1);
61+
fwrite($readStream, "x", 1);
62+
fseek($readStream, 0, SEEK_SET);
63+
$streams = [$readStream];
64+
$empty = [];
65+
try {
66+
stream_select($streams, $streams,$empty, 0);
67+
} catch (ValueError $e) {
68+
echo $e->getMessage(), "\n";
69+
}
70+
fflush($readStream);
71+
try {
72+
fclose($readStream);
73+
} catch (TypeError $e) {
74+
echo $e->getMessage(), "\n";
75+
}
76+
77+
?>
78+
--EXPECTF--
79+
Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d
80+
81+
Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d
82+
83+
Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d
84+
85+
Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d
86+
87+
Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d
88+
89+
Warning: stream_select(): Cannot represent a stream of type user-space as a select()able descriptor in %s on line %d
90+
91+
Warning: fclose(): cannot close the provided stream, as it must not be manually closed in %s on line %d
92+
93+
Warning: stream_select(): Cannot represent a stream of type user-space as a select()able descriptor in %s on line %d
94+
No stream arrays were passed
95+
fclose(): Argument #1 ($stream) must be an open stream resource

0 commit comments

Comments
 (0)