Skip to content

Commit c4a383d

Browse files
committed
Fix ht corruption during shutdown for bailing user stream
Fixes GH-19844
1 parent 4ad4d54 commit c4a383d

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

Zend/tests/gh19844.phpt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
--TEST--
2+
GH-19844: Bail from stream_close() in zend_shutdown_executor_values()
3+
--FILE--
4+
<?php
5+
6+
class Test {
7+
public $context;
8+
private static $nested = false;
9+
10+
function stream_open() {
11+
return true;
12+
}
13+
14+
function stream_read() {
15+
return '.';
16+
}
17+
function stream_set_option() {}
18+
function stream_stat() {}
19+
20+
function stream_eof() {
21+
if (!Test::$nested) {
22+
Test::$nested = true;
23+
include 'Test://';
24+
}
25+
@trigger_error('Bail', E_USER_ERROR);
26+
}
27+
28+
function stream_close() {
29+
@trigger_error('Bail', E_USER_ERROR);
30+
}
31+
}
32+
33+
stream_wrapper_register('Test', Test::class);
34+
include 'Test://';
35+
36+
?>
37+
--EXPECTF--
38+
Fatal error: Bail in %s on line %d
39+
40+
Fatal error: Bail in %s on line %d

Zend/zend_execute_API.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,11 @@ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown)
276276
EG(flags) |= EG_FLAGS_IN_RESOURCE_SHUTDOWN;
277277
zend_try {
278278
zend_close_rsrc_list(&EG(regular_list));
279+
} zend_catch {
280+
/* If we have bailed, we probably executed user code (e.g. user stream API).
281+
* Avoid triggering it again when destroying the list in zend_deactivate(),
282+
* after the executor has already shut down. */
283+
EG(regular_list).pDestructor = NULL;
279284
} zend_end_try();
280285

281286
/* No PHP callback functions should be called after this point. */

0 commit comments

Comments
 (0)