Skip to content

Commit d74d0e4

Browse files
committed
Continue closing resources even after bailout
1 parent c4a383d commit d74d0e4

File tree

3 files changed

+20
-15
lines changed

3 files changed

+20
-15
lines changed

Zend/tests/gh19844.phpt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,5 @@ include 'Test://';
3838
Fatal error: Bail in %s on line %d
3939

4040
Fatal error: Bail in %s on line %d
41+
42+
Fatal error: Bail in %s on line %d

Zend/zend_execute_API.c

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -274,14 +274,7 @@ ZEND_API void zend_shutdown_executor_values(bool fast_shutdown)
274274
zval *zv;
275275

276276
EG(flags) |= EG_FLAGS_IN_RESOURCE_SHUTDOWN;
277-
zend_try {
278-
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;
284-
} zend_end_try();
277+
zend_close_rsrc_list(&EG(regular_list));
285278

286279
/* No PHP callback functions should be called after this point. */
287280
EG(active) = 0;

Zend/zend_list.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,15 +217,25 @@ void zend_close_rsrc_list(HashTable *ht)
217217
/* Reload ht->arData on each iteration, as it may be reallocated. */
218218
uint32_t i = ht->nNumUsed;
219219

220-
while (i-- > 0) {
221-
zval *p = ZEND_HASH_ELEMENT(ht, i);
222-
if (Z_TYPE_P(p) != IS_UNDEF) {
223-
zend_resource *res = Z_PTR_P(p);
224-
if (res->type >= 0) {
225-
zend_resource_dtor(res);
220+
retry:
221+
zend_try {
222+
while (i-- > 0) {
223+
zval *p = ZEND_HASH_ELEMENT(ht, i);
224+
if (Z_TYPE_P(p) != IS_UNDEF) {
225+
zend_resource *res = Z_PTR_P(p);
226+
if (res->type >= 0) {
227+
zend_resource_dtor(res);
228+
}
226229
}
227230
}
228-
}
231+
} zend_catch {
232+
/* If we have bailed, we probably executed user code (e.g. user stream
233+
* API). Keep closing resources so they don't leak. User handlers must be
234+
* called now so they aren't called in zend_deactivate() on
235+
* zend_destroy_rsrc_list(&EG(regular_list)). At that point, the executor
236+
* has already shut down and the process would crash. */
237+
goto retry;
238+
} zend_end_try();
229239
}
230240

231241

0 commit comments

Comments
 (0)