diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2020-03-02 10:45:37 +0100 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2020-03-02 10:45:37 +0100 |
commit | 2adf1c4d23467424012db1971d0a0a678d10d782 (patch) | |
tree | a222bfb3f5bc98f959dadaf6ac0acf3c09d95bea /ext/com_dotnet | |
parent | 6c48da9a50a68cbb27873ead6bf936494c006236 (diff) | |
download | php-git-2adf1c4d23467424012db1971d0a0a678d10d782.tar.gz |
Fix #79332: php_istreams are never freed
Releasing the `com_dotnet_istream_wrapper` in `istream_destructor()` is
pointless, since `istream_destructor()` is only called when the
resource is going to be released. This recursion is not a real issue,
though, since the resource is never exposed to userland, and has at
most refcount 1, so due to well defined unsigned integer underflow, it
never is released twice. However, returning early in this case causes
a memory leak which needs to be fixed.
Diffstat (limited to 'ext/com_dotnet')
-rw-r--r-- | ext/com_dotnet/com_persist.c | 11 | ||||
-rw-r--r-- | ext/com_dotnet/tests/bug79332.phpt | 18 |
2 files changed, 19 insertions, 10 deletions
diff --git a/ext/com_dotnet/com_persist.c b/ext/com_dotnet/com_persist.c index 0fee0efd43..743a441f70 100644 --- a/ext/com_dotnet/com_persist.c +++ b/ext/com_dotnet/com_persist.c @@ -248,13 +248,6 @@ static struct IStreamVtbl php_istream_vtbl = { static void istream_destructor(php_istream *stm) { - if (stm->res) { - zend_resource *res = stm->res; - stm->res = NULL; - zend_list_delete(res); - return; - } - if (stm->refcount > 0) { CoDisconnectObject((IUnknown*)stm, 0); } @@ -268,7 +261,6 @@ static void istream_destructor(php_istream *stm) PHP_COM_DOTNET_API IStream *php_com_wrapper_export_stream(php_stream *stream) { php_istream *stm = (php_istream*)CoTaskMemAlloc(sizeof(*stm)); - zval *tmp; if (stm == NULL) return NULL; @@ -280,8 +272,7 @@ PHP_COM_DOTNET_API IStream *php_com_wrapper_export_stream(php_stream *stream) stm->stream = stream; GC_ADDREF(stream->res); - tmp = zend_list_insert(stm, le_istream); - stm->res = Z_RES_P(tmp); + stm->res = zend_register_resource(stm, le_istream); return (IStream*)stm; } diff --git a/ext/com_dotnet/tests/bug79332.phpt b/ext/com_dotnet/tests/bug79332.phpt new file mode 100644 index 0000000000..45856b5488 --- /dev/null +++ b/ext/com_dotnet/tests/bug79332.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #79332 (php_istreams are never freed) +--SKIPIF-- +<?php +if (!extension_loaded('com_dotnet')) die('com_dotnet extension not available'); +?> +--FILE-- +<?php +$ph = new COMPersistHelper(null); +try { + $ph->LoadFromStream(fopen(__FILE__, 'r')); +} catch (com_exception $ex) { + // use hard-coded message to avoid localization issues + echo "A com_exception has been thrown\n"; +} +?> +--EXPECT-- +A com_exception has been thrown |