Fix memory leak if calling SoapServer::setClass() twice

Closes GH-14381.
This commit is contained in:
Niels Dossche 2024-05-30 23:41:56 +02:00
parent 51bb9c2c2a
commit 23912f55eb
No known key found for this signature in database
GPG key ID: B8A8AD166DF0E2E5
3 changed files with 35 additions and 7 deletions

1
NEWS
View file

@ -30,6 +30,7 @@ PHP NEWS
. Fixed bug #47925 (PHPClient can't decompress response). (nielsdos) . Fixed bug #47925 (PHPClient can't decompress response). (nielsdos)
. Fix missing error restore code. (nielsdos) . Fix missing error restore code. (nielsdos)
. Fix memory leak if calling SoapServer::setObject() twice. (nielsdos) . Fix memory leak if calling SoapServer::setObject() twice. (nielsdos)
. Fix memory leak if calling SoapServer::setClass() twice. (nielsdos)
- Sodium: - Sodium:
. Fix memory leaks in ext/sodium on failure of some functions. (nielsdos) . Fix memory leaks in ext/sodium on failure of some functions. (nielsdos)

View file

@ -66,6 +66,7 @@ static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName,
static void delete_service(void *service); static void delete_service(void *service);
static void delete_url(void *handle); static void delete_url(void *handle);
static void delete_hashtable(void *hashtable); static void delete_hashtable(void *hashtable);
static void delete_argv(struct _soap_class *class);
static void soap_error_handler(int error_num, zend_string *error_filename, const uint32_t error_lineno, zend_string *message); static void soap_error_handler(int error_num, zend_string *error_filename, const uint32_t error_lineno, zend_string *message);
@ -928,6 +929,8 @@ PHP_METHOD(SoapServer, setClass)
service->type = SOAP_CLASS; service->type = SOAP_CLASS;
service->soap_class.ce = ce; service->soap_class.ce = ce;
delete_argv(&service->soap_class);
service->soap_class.persistence = SOAP_PERSISTENCE_REQUEST; service->soap_class.persistence = SOAP_PERSISTENCE_REQUEST;
service->soap_class.argc = num_args; service->soap_class.argc = num_args;
if (service->soap_class.argc > 0) { if (service->soap_class.argc > 0) {
@ -4347,6 +4350,16 @@ static void delete_url(void *handle) /* {{{ */
} }
/* }}} */ /* }}} */
static void delete_argv(struct _soap_class *class)
{
if (class->argc) {
for (int i = 0; i < class->argc; i++) {
zval_ptr_dtor(&class->argv[i]);
}
efree(class->argv);
}
}
static void delete_service(void *data) /* {{{ */ static void delete_service(void *data) /* {{{ */
{ {
soapServicePtr service = (soapServicePtr)data; soapServicePtr service = (soapServicePtr)data;
@ -4361,13 +4374,7 @@ static void delete_service(void *data) /* {{{ */
efree(service->typemap); efree(service->typemap);
} }
if (service->soap_class.argc) { delete_argv(&service->soap_class);
int i;
for (i = 0; i < service->soap_class.argc;i++) {
zval_ptr_dtor(&service->soap_class.argv[i]);
}
efree(service->soap_class.argv);
}
if (service->actor) { if (service->actor) {
efree(service->actor); efree(service->actor);

View file

@ -0,0 +1,20 @@
--TEST--
SOAP Server: SoapServer::setClass() twice
--EXTENSIONS--
soap
--FILE--
<?php
class Foo {
function test() {
return "Hello World";
}
}
$server = new SoapServer(null,array('uri'=>"http://testuri.org"));
$server->setClass(Foo::class, new stdClass, []);
$server->setClass(Foo::class, new stdClass, []);
echo "Done\n";
?>
--EXPECT--
Done