From 7d1ea234ff761fc0073a105b95ed285472e50485 Mon Sep 17 00:00:00 2001 From: Antony Dovgal Date: Mon, 16 May 2005 08:37:41 +0000 Subject: [PATCH] MFH: fix bugs #32742 (segmentation fault when the stream with a wrapper is not closed), #32171 (Userspace stream wrapper crashes PHP) --- NEWS | 3 +++ ext/standard/basic_functions.c | 15 ++++----------- main/main.c | 8 ++++++++ main/php_streams.h | 1 + main/streams/streams.c | 15 +++++++++++++++ 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/NEWS b/NEWS index ed4483b358..e4b4e7304a 100644 --- a/NEWS +++ b/NEWS @@ -32,6 +32,8 @@ PHP NEWS - Fixed bug #32755 (Segfault in replaceChild() when DocumentFragment has no children). (Rob) - Fixed bug #32753 (Undefined constant SQLITE_NOTADB). (Ilia) +- Fixed bug #32742 (segmentation fault when the stream with a wrapper + is not closed). (Tony, Dmitry) - Fixed bug #32699 (pg_affected_rows() was defined when it was not available). (Derick) - Fixed bug #32686 (Require/include file in destructor causes segfault). @@ -65,6 +67,7 @@ PHP NEWS 5.0.3). (Dmitry) - Fixed bug #32245 (xml_parser_free() in a function assigned to the xml parser gives a segfault). (Rob) +- Fixed bug #32171 (Userspace stream wrapper crashes PHP). (Tony, Dmitry) - Fixed bug #32080 (segfault when assigning object to itself with zend.ze1_compatibility_mode=On). (Dmitry) - Fixed bug #32013 (ext/mysqli bind_result causes fatal error: memory diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 5d824751fb..519e933d5b 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -1191,17 +1191,10 @@ PHP_RSHUTDOWN_FUNCTION(basic) } STR_FREE(BG(locale_string)); - if (FG(stream_wrappers)) { - zend_hash_destroy(FG(stream_wrappers)); - efree(FG(stream_wrappers)); - FG(stream_wrappers) = NULL; - } - - if (FG(stream_filters)) { - zend_hash_destroy(FG(stream_filters)); - efree(FG(stream_filters)); - FG(stream_filters) = NULL; - } + /* + FG(stream_wrappers) and FG(stream_filters) are destroyed + during php_request_shutdown() + */ PHP_RSHUTDOWN(filestat)(SHUTDOWN_FUNC_ARGS_PASSTHRU); #ifdef HAVE_SYSLOG_H diff --git a/main/main.c b/main/main.c index bd9497752c..e07d02f096 100644 --- a/main/main.c +++ b/main/main.c @@ -1161,6 +1161,10 @@ void php_request_shutdown_for_hook(void *dummy) sapi_deactivate(TSRMLS_C); } zend_end_try(); + zend_try { + php_shutdown_stream_hashes(TSRMLS_C); + } zend_end_try(); + zend_try { shutdown_memory_manager(CG(unclean_shutdown), 0 TSRMLS_CC); } zend_end_try(); @@ -1227,6 +1231,10 @@ void php_request_shutdown(void *dummy) sapi_deactivate(TSRMLS_C); } zend_end_try(); + zend_try { + php_shutdown_stream_hashes(TSRMLS_C); + } zend_end_try(); + zend_try { shutdown_memory_manager(CG(unclean_shutdown) || !report_memleaks, 0 TSRMLS_CC); } zend_end_try(); diff --git a/main/php_streams.h b/main/php_streams.h index 2ae36e407f..f6ab2d4857 100755 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -505,6 +505,7 @@ END_EXTERN_C() int php_init_stream_wrappers(int module_number TSRMLS_DC); int php_shutdown_stream_wrappers(int module_number TSRMLS_DC); +void php_shutdown_stream_hashes(TSRMLS_D); PHP_RSHUTDOWN_FUNCTION(streams); BEGIN_EXTERN_C() diff --git a/main/streams/streams.c b/main/streams/streams.c index 01541a67ef..144b24cc90 100755 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -1367,6 +1367,21 @@ static void stream_resource_persistent_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC FG(pclose_ret) = php_stream_free(stream, PHP_STREAM_FREE_CLOSE | PHP_STREAM_FREE_RSRC_DTOR); } +void php_shutdown_stream_hashes(TSRMLS_D) +{ + if (FG(stream_wrappers)) { + zend_hash_destroy(FG(stream_wrappers)); + efree(FG(stream_wrappers)); + FG(stream_wrappers) = NULL; + } + + if (FG(stream_filters)) { + zend_hash_destroy(FG(stream_filters)); + efree(FG(stream_filters)); + FG(stream_filters) = NULL; + } +} + int php_init_stream_wrappers(int module_number TSRMLS_DC) { le_stream = zend_register_list_destructors_ex(stream_resource_regular_dtor, NULL, "stream", module_number); -- 2.40.0