]> granicus.if.org Git - php/commitdiff
Avoid double-freeing streams.
authorWez Furlong <wez@php.net>
Mon, 6 Jun 2005 01:51:48 +0000 (01:51 +0000)
committerWez Furlong <wez@php.net>
Mon, 6 Jun 2005 01:51:48 +0000 (01:51 +0000)
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.

Zend/zend_language_scanner.l
main/main.c

index 7cd266fd39e030f7c04e107cab97a799de005f29..350cdfa664dd6dce4c46b36ad9249bd7c51ef0ca 100644 (file)
@@ -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,
index f64a35cc429987cecfabe0ac976b449a79ff9f3e..b61b6a8f9eb6cb1945d1bf22baeee13fe22b7ed5 100644 (file)
@@ -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;
        }