Skip to content

Commit 27797a2

Browse files
committed
Fix bug #75306: Memleak in SoapClient
Setting the stream context via php_stream_context_to_zval() will increase the reference count. So if the new context is created, then it will end up with a reference count of 2 while it should be 1. Credits to cmb for the analysis. I arrived at the same patch as he did. Closes GH-12523.
1 parent 9f7f3b2 commit 27797a2

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ PHP NEWS
3636
. Fix segfault and assertion failure with refcounted props and arrays.
3737
(nielsdos)
3838
. Fix potential crash with an edge case of persistent encoders. (nielsdos)
39+
. Fixed bug #75306 (Memleak in SoapClient). (nielsdos)
3940

4041
- Streams:
4142
. Fixed bug #75708 (getimagesize with "&$imageinfo" fails on StreamWrappers).

ext/soap/php_sdl.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3255,6 +3255,9 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl)
32553255
tmp = Z_CLIENT_STREAM_CONTEXT_P(this_ptr);
32563256
if (Z_TYPE_P(tmp) == IS_RESOURCE) {
32573257
context = php_stream_context_from_zval(tmp, 0);
3258+
/* Share a reference with new_context down below.
3259+
* For new contexts, the reference is only in new_context so that doesn't need extra refcounting. */
3260+
GC_ADDREF(context->res);
32583261
}
32593262

32603263
tmp = Z_CLIENT_USER_AGENT_P(this_ptr);
@@ -3323,7 +3326,7 @@ sdlPtr get_sdl(zval *this_ptr, char *uri, zend_long cache_wsdl)
33233326
}
33243327

33253328
if (context) {
3326-
php_stream_context_to_zval(context, &new_context);
3329+
ZVAL_RES(&new_context, context->res);
33273330
php_libxml_switch_context(&new_context, &orig_context);
33283331
}
33293332

ext/soap/tests/bug75306.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Bug #75306 (Memleak in SoapClient)
3+
--EXTENSIONS--
4+
soap
5+
--FILE--
6+
<?php
7+
$options = array("cache_wsdl" => WSDL_CACHE_NONE);
8+
// Need a warm-up for globals
9+
for ($i = 0; $i < 10; $i++) {
10+
$client = new SoapClient("ext/soap/tests/test.wsdl", $options);
11+
}
12+
$usage = memory_get_usage();
13+
for ($i = 0; $i < 10; $i++) {
14+
$client = new SoapClient("ext/soap/tests/test.wsdl", $options);
15+
}
16+
$usage_delta = memory_get_usage() - $usage;
17+
var_dump($usage_delta);
18+
?>
19+
--EXPECT--
20+
int(0)

0 commit comments

Comments
 (0)