Skip to content

Commit f4280b1

Browse files
committed
fix segfault on streams destruction
1 parent d354d83 commit f4280b1

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
--TEST--
2+
GH-20286 use after destroy on userland stream_close
3+
--CREDITS--
4+
vi3tL0u1s
5+
--FILE--
6+
<?php
7+
class lib {
8+
function stream_open() {
9+
return true;
10+
}
11+
12+
function stream_read($count) {
13+
function a() {}
14+
include('lib://');
15+
}
16+
17+
function stream_close() {
18+
include('lib://');
19+
}
20+
}
21+
stream_wrapper_register('lib', lib::class);
22+
include('lib://test.php');
23+
?>
24+
--EXPECTF--
25+
26+
Deprecated: Creation of dynamic property lib::$context is deprecated in %s on line %d
27+
28+
Warning: include(): lib::stream_set_option is not implemented! in %s on line %d
29+
30+
Warning: include(): lib::stream_stat is not implemented! in %s on line %d
31+
32+
Deprecated: Creation of dynamic property lib::$context is deprecated in %s on line %d
33+
34+
Warning: include(): lib::stream_set_option is not implemented! in %s on line %d
35+
36+
Warning: include(): lib::stream_stat is not implemented! in %s on line %d
37+
38+
Fatal error: Cannot redeclare a() (previously declared in %s:%d) %s on line %d
39+
40+
Deprecated: Creation of dynamic property lib::$context is deprecated in %s on line %d
41+
42+
Warning: include(): lib::stream_set_option is not implemented! in %s on line %d
43+
44+
Warning: include(): lib::stream_stat is not implemented! in %s on line %d
45+
46+
Fatal error: Cannot redeclare a() (previously declared in %s:%d) %s on line %d
47+
48+
Deprecated: Creation of dynamic property lib::$context is deprecated in %s on line %d
49+
50+
Warning: include(): lib::stream_set_option is not implemented! in %s on line %d
51+
52+
Warning: include(): lib::stream_stat is not implemented! in %s on line %d
53+
54+
Fatal error: Cannot redeclare a() (previously declared in %s:%d) %s on line %d

main/streams/userspace.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -695,6 +695,10 @@ static int php_userstreamop_close(php_stream *stream, int close_handle)
695695

696696
assert(us != NULL);
697697

698+
if (UNEXPECTED(stream->wrapper->wops != &user_stream_wops)) {
699+
stream->wrapper->wops = &user_stream_wops;
700+
}
701+
698702
ZVAL_STRINGL(&func_name, USERSTREAM_CLOSE, sizeof(USERSTREAM_CLOSE)-1);
699703

700704
call_method_if_exists(&us->object, &func_name, &retval, 0, NULL);

0 commit comments

Comments
 (0)