diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index 3dd8e6c5d76e..09f38f67bc41 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -3243,6 +3243,9 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl) tmp = Z_CLIENT_STREAM_CONTEXT_P(this_ptr); if (Z_TYPE_P(tmp) == IS_RESOURCE) { context = php_stream_context_from_zval(tmp, 0); + /* Share a reference with new_context down below. + * For new contexts, the reference is only in new_context so that doesn't need extra refcounting. */ + GC_ADDREF(context->res); } tmp = Z_CLIENT_USER_AGENT_P(this_ptr); @@ -3311,7 +3314,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl) } if (context) { - php_stream_context_to_zval(context, &new_context); + ZVAL_RES(&new_context, context->res); php_libxml_switch_context(&new_context, &orig_context); } diff --git a/ext/soap/tests/bug75306.phpt b/ext/soap/tests/bug75306.phpt new file mode 100644 index 000000000000..7501fde59e6b --- /dev/null +++ b/ext/soap/tests/bug75306.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #75306 (Memleak in SoapClient) +--EXTENSIONS-- +soap +--FILE-- + WSDL_CACHE_NONE); +// Need a warm-up for globals +for ($i = 0; $i < 10; $i++) { + $client = new SoapClient("ext/soap/tests/test.wsdl", $options); +} +$usage = memory_get_usage(); +for ($i = 0; $i < 10; $i++) { + $client = new SoapClient("ext/soap/tests/test.wsdl", $options); +} +$usage_delta = memory_get_usage() - $usage; +var_dump($usage_delta); +?> +--EXPECT-- +int(0)