From: Wez Furlong Date: Mon, 6 Jun 2005 01:51:48 +0000 (+0000) Subject: Avoid double-freeing streams. X-Git-Tag: php-5.0.1b1~81 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=42ada22e0c9de8b8e2eab294f91103a90b42829b;p=php Avoid double-freeing streams. This can happen because all streams are registered as resources; the engine also tracks them in the open_files global. Avoid the potential for double-freeing by simply making streams exposed to the engine have no closer for the engine to call; they will already be in the resource list, and thus will be shut down properly at request end. --- diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 7cd266fd39..350cdfa664 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -244,7 +244,9 @@ ZEND_API void zend_file_handle_dtor(zend_file_handle *fh) fclose(fh->handle.fp); break; case ZEND_HANDLE_STREAM: - fh->handle.stream.closer(fh->handle.stream.handle TSRMLS_CC); + if (fh->handle.stream.closer) { + fh->handle.stream.closer(fh->handle.stream.handle TSRMLS_CC); + } break; case ZEND_HANDLE_FILENAME: /* We're only supposed to get here when destructing the used_files hash, diff --git a/main/main.c b/main/main.c index f64a35cc42..b61b6a8f9e 100644 --- a/main/main.c +++ b/main/main.c @@ -857,9 +857,14 @@ static int php_stream_open_for_zend(const char *filename, zend_file_handle *hand handle->free_filename = 0; handle->handle.stream.handle = stream; handle->handle.stream.reader = (zend_stream_reader_t)_php_stream_read; - handle->handle.stream.closer = stream_closer_for_zend; + /* don't set this; all streams are tracked as part of the resource system, + * and we'll end up double-free'ing them if we allow zend to close them + * down after the resource list has been cleaned up */ + handle->handle.stream.closer = NULL; /* stream_closer_for_zend; */ handle->handle.stream.fteller = stream_fteller_for_zend; handle->handle.stream.interactive = 0; + /* suppress warning if this stream is not explicitly closed */ + php_stream_auto_cleanup(stream); return SUCCESS; }