Skip to content

Commit 23912f5

Browse files
committed
Fix memory leak if calling SoapServer::setClass() twice
Closes GH-14381.
1 parent 51bb9c2 commit 23912f5

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ PHP NEWS
3030
. Fixed bug #47925 (PHPClient can't decompress response). (nielsdos)
3131
. Fix missing error restore code. (nielsdos)
3232
. Fix memory leak if calling SoapServer::setObject() twice. (nielsdos)
33+
. Fix memory leak if calling SoapServer::setClass() twice. (nielsdos)
3334

3435
- Sodium:
3536
. Fix memory leaks in ext/sodium on failure of some functions. (nielsdos)

ext/soap/soap.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName,
6666
static void delete_service(void *service);
6767
static void delete_url(void *handle);
6868
static void delete_hashtable(void *hashtable);
69+
static void delete_argv(struct _soap_class *class);
6970

7071
static void soap_error_handler(int error_num, zend_string *error_filename, const uint32_t error_lineno, zend_string *message);
7172

@@ -928,6 +929,8 @@ PHP_METHOD(SoapServer, setClass)
928929
service->type = SOAP_CLASS;
929930
service->soap_class.ce = ce;
930931

932+
delete_argv(&service->soap_class);
933+
931934
service->soap_class.persistence = SOAP_PERSISTENCE_REQUEST;
932935
service->soap_class.argc = num_args;
933936
if (service->soap_class.argc > 0) {
@@ -4347,6 +4350,16 @@ static void delete_url(void *handle) /* {{{ */
43474350
}
43484351
/* }}} */
43494352

4353+
static void delete_argv(struct _soap_class *class)
4354+
{
4355+
if (class->argc) {
4356+
for (int i = 0; i < class->argc; i++) {
4357+
zval_ptr_dtor(&class->argv[i]);
4358+
}
4359+
efree(class->argv);
4360+
}
4361+
}
4362+
43504363
static void delete_service(void *data) /* {{{ */
43514364
{
43524365
soapServicePtr service = (soapServicePtr)data;
@@ -4361,13 +4374,7 @@ static void delete_service(void *data) /* {{{ */
43614374
efree(service->typemap);
43624375
}
43634376

4364-
if (service->soap_class.argc) {
4365-
int i;
4366-
for (i = 0; i < service->soap_class.argc;i++) {
4367-
zval_ptr_dtor(&service->soap_class.argv[i]);
4368-
}
4369-
efree(service->soap_class.argv);
4370-
}
4377+
delete_argv(&service->soap_class);
43714378

43724379
if (service->actor) {
43734380
efree(service->actor);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
SOAP Server: SoapServer::setClass() twice
3+
--EXTENSIONS--
4+
soap
5+
--FILE--
6+
<?php
7+
class Foo {
8+
function test() {
9+
return "Hello World";
10+
}
11+
}
12+
13+
$server = new SoapServer(null,array('uri'=>"http://testuri.org"));
14+
$server->setClass(Foo::class, new stdClass, []);
15+
$server->setClass(Foo::class, new stdClass, []);
16+
17+
echo "Done\n";
18+
?>
19+
--EXPECT--
20+
Done

0 commit comments

Comments
 (0)