From d7aa0be3a86d45bb60b212d01fdaeec76030c86e Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 31 May 2024 18:18:40 +0200 Subject: [PATCH 1/5] Fix GH-14368: Test failure in ext/session/tests/gh13856.phpt (#14378) If the runner overrides session.save_path, the test fails. Manually set it to a value known to trigger the issue. --- ext/session/tests/gh13856.phpt | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/session/tests/gh13856.phpt b/ext/session/tests/gh13856.phpt index a6d9fa0eaed..e503d41d29a 100644 --- a/ext/session/tests/gh13856.phpt +++ b/ext/session/tests/gh13856.phpt @@ -6,6 +6,7 @@ session session.save_handler=files open_basedir=. error_reporting=E_ALL +session.save_path= --FILE-- Date: Fri, 31 May 2024 18:19:00 +0200 Subject: [PATCH 2/5] Fix missing error restore code in ext-soap (#14379) The begin and end macros should be paired, but some of the end macro calls were missing. --- NEWS | 1 + ext/soap/soap.c | 12 ++++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 98a3b51a4c5..3c8204aec3d 100644 --- a/NEWS +++ b/NEWS @@ -28,6 +28,7 @@ PHP NEWS - Soap: . Fixed bug #47925 (PHPClient can't decompress response). (nielsdos) + . Fix missing error restore code. (nielsdos) - Sodium: . Fix memory leaks in ext/sodium on failure of some functions. (nielsdos) diff --git a/ext/soap/soap.c b/ext/soap/soap.c index de29917cd87..690077ff1ef 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -899,11 +899,9 @@ PHP_METHOD(SoapServer, setPersistence) zend_argument_value_error( 1, "must be either SOAP_PERSISTENCE_SESSION or SOAP_PERSISTENCE_REQUEST when the SOAP server is used in class mode" ); - RETURN_THROWS(); } } else { zend_throw_error(NULL, "SoapServer::setPersistence(): Persistence cannot be set when the SOAP server is used in function mode"); - RETURN_THROWS(); } SOAP_SERVER_END_CODE(); @@ -1042,6 +1040,7 @@ PHP_METHOD(SoapServer, addFunction) if (Z_TYPE_P(tmp_function) != IS_STRING) { zend_argument_type_error(1, "must contain only strings"); + SOAP_SERVER_END_CODE(); RETURN_THROWS(); } @@ -1049,6 +1048,7 @@ PHP_METHOD(SoapServer, addFunction) if ((f = zend_hash_find_ptr(EG(function_table), key)) == NULL) { zend_type_error("SoapServer::addFunction(): Function \"%s\" not found", Z_STRVAL_P(tmp_function)); + SOAP_SERVER_END_CODE(); RETURN_THROWS(); } @@ -1066,6 +1066,7 @@ PHP_METHOD(SoapServer, addFunction) if ((f = zend_hash_find_ptr(EG(function_table), key)) == NULL) { zend_argument_type_error(1, "must be a valid function name, function \"%s\" not found", Z_STRVAL_P(function_name)); + SOAP_SERVER_END_CODE(); RETURN_THROWS(); } if (service->soap_functions.ft == NULL) { @@ -1086,11 +1087,9 @@ PHP_METHOD(SoapServer, addFunction) service->soap_functions.functions_all = TRUE; } else { zend_argument_value_error(1, "must be SOAP_FUNCTIONS_ALL when an integer is passed"); - RETURN_THROWS(); } } else { zend_argument_type_error(1, "must be of type array|string|int, %s given", zend_zval_type_name(function_name)); - RETURN_THROWS(); } SOAP_SERVER_END_CODE(); @@ -1150,6 +1149,7 @@ PHP_METHOD(SoapServer, handle) if (arg && ZEND_SIZE_T_INT_OVFL(arg_len)) { soap_server_fault("Server", "Input string is too long", NULL, NULL, NULL); + SOAP_SERVER_END_CODE(); return; } @@ -1231,10 +1231,12 @@ PHP_METHOD(SoapServer, handle) php_stream_filter_append(&SG(request_info).request_body->readfilters, zf); } else { php_error_docref(NULL, E_WARNING,"Can't uncompress compressed request"); + SOAP_SERVER_END_CODE(); return; } } else { php_error_docref(NULL, E_WARNING,"Request is compressed with unknown compression '%s'",Z_STRVAL_P(encoding)); + SOAP_SERVER_END_CODE(); return; } } @@ -1246,6 +1248,7 @@ PHP_METHOD(SoapServer, handle) } } else { zval_ptr_dtor(&retval); + SOAP_SERVER_END_CODE(); return; } } else { @@ -1622,6 +1625,7 @@ PHP_METHOD(SoapServer, addSoapHeader) if (!service || !service->soap_headers_ptr) { zend_throw_error(NULL, "SoapServer::addSoapHeader() may be called only during SOAP request processing"); + SOAP_SERVER_END_CODE(); RETURN_THROWS(); } From 51bb9c2c2a1e553430dd37c2317c43309cd63931 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 30 May 2024 23:34:39 +0200 Subject: [PATCH 3/5] Fix memory leak if calling SoapServer::setObject() twice Closes GH-14380. --- NEWS | 1 + ext/soap/soap.c | 1 + ext/soap/tests/bugs/setObject_twice.phpt | 14 ++++++++++++++ 3 files changed, 16 insertions(+) create mode 100644 ext/soap/tests/bugs/setObject_twice.phpt diff --git a/NEWS b/NEWS index 3c8204aec3d..e13d1a6c03f 100644 --- a/NEWS +++ b/NEWS @@ -29,6 +29,7 @@ PHP NEWS - Soap: . Fixed bug #47925 (PHPClient can't decompress response). (nielsdos) . Fix missing error restore code. (nielsdos) + . Fix memory leak if calling SoapServer::setObject() twice. (nielsdos) - Sodium: . Fix memory leaks in ext/sodium on failure of some functions. (nielsdos) diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 690077ff1ef..a64509479b4 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -959,6 +959,7 @@ PHP_METHOD(SoapServer, setObject) service->type = SOAP_OBJECT; + zval_ptr_dtor(&service->soap_object); ZVAL_OBJ_COPY(&service->soap_object, Z_OBJ_P(obj)); SOAP_SERVER_END_CODE(); diff --git a/ext/soap/tests/bugs/setObject_twice.phpt b/ext/soap/tests/bugs/setObject_twice.phpt new file mode 100644 index 00000000000..16157e134b0 --- /dev/null +++ b/ext/soap/tests/bugs/setObject_twice.phpt @@ -0,0 +1,14 @@ +--TEST-- +SOAP Server: SoapServer::setObject twice +--EXTENSIONS-- +soap +--FILE-- +"http://testuri.org")); +$server->setObject($foo); +$server->setObject($foo); +echo "Done\n"; +?> +--EXPECT-- +Done From 23912f55eb2c4b3d2032e9bc49ea8231df08e96e Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 30 May 2024 23:41:56 +0200 Subject: [PATCH 4/5] Fix memory leak if calling SoapServer::setClass() twice Closes GH-14381. --- NEWS | 1 + ext/soap/soap.c | 21 ++++++++++++++------- ext/soap/tests/bugs/setClass_twice.phpt | 20 ++++++++++++++++++++ 3 files changed, 35 insertions(+), 7 deletions(-) create mode 100644 ext/soap/tests/bugs/setClass_twice.phpt diff --git a/NEWS b/NEWS index e13d1a6c03f..0091640a2d5 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,7 @@ PHP NEWS . Fixed bug #47925 (PHPClient can't decompress response). (nielsdos) . Fix missing error restore code. (nielsdos) . Fix memory leak if calling SoapServer::setObject() twice. (nielsdos) + . Fix memory leak if calling SoapServer::setClass() twice. (nielsdos) - Sodium: . Fix memory leaks in ext/sodium on failure of some functions. (nielsdos) diff --git a/ext/soap/soap.c b/ext/soap/soap.c index a64509479b4..809935f57d8 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -66,6 +66,7 @@ static xmlNodePtr serialize_zval(zval *val, sdlParamPtr param, char *paramName, static void delete_service(void *service); static void delete_url(void *handle); 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); @@ -928,6 +929,8 @@ PHP_METHOD(SoapServer, setClass) service->type = SOAP_CLASS; service->soap_class.ce = ce; + delete_argv(&service->soap_class); + service->soap_class.persistence = SOAP_PERSISTENCE_REQUEST; service->soap_class.argc = num_args; 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) /* {{{ */ { soapServicePtr service = (soapServicePtr)data; @@ -4361,13 +4374,7 @@ static void delete_service(void *data) /* {{{ */ efree(service->typemap); } - if (service->soap_class.argc) { - int i; - for (i = 0; i < service->soap_class.argc;i++) { - zval_ptr_dtor(&service->soap_class.argv[i]); - } - efree(service->soap_class.argv); - } + delete_argv(&service->soap_class); if (service->actor) { efree(service->actor); diff --git a/ext/soap/tests/bugs/setClass_twice.phpt b/ext/soap/tests/bugs/setClass_twice.phpt new file mode 100644 index 00000000000..0651e2dbec2 --- /dev/null +++ b/ext/soap/tests/bugs/setClass_twice.phpt @@ -0,0 +1,20 @@ +--TEST-- +SOAP Server: SoapServer::setClass() twice +--EXTENSIONS-- +soap +--FILE-- +"http://testuri.org")); +$server->setClass(Foo::class, new stdClass, []); +$server->setClass(Foo::class, new stdClass, []); + +echo "Done\n"; +?> +--EXPECT-- +Done From 89c4db9c22072f6f98790d0101abb7692ba18762 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Thu, 30 May 2024 23:48:48 +0200 Subject: [PATCH 5/5] Fix reading zlib ini settings in ext-soap zend_ini_long() actually expects the length without the NUL byte, but we're passing the length *with* the NUL byte. This mess can actually be avoided altogether by using INI_INT, so use that instead. Closes GH-14382. --- NEWS | 1 + ext/soap/soap.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 0091640a2d5..283455d4c77 100644 --- a/NEWS +++ b/NEWS @@ -31,6 +31,7 @@ PHP NEWS . Fix missing error restore code. (nielsdos) . Fix memory leak if calling SoapServer::setObject() twice. (nielsdos) . Fix memory leak if calling SoapServer::setClass() twice. (nielsdos) + . Fix reading zlib ini settings in ext-soap. (nielsdos) - Sodium: . Fix memory leaks in ext/sodium on failure of some functions. (nielsdos) diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 809935f57d8..0184eab7bb3 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -1527,7 +1527,7 @@ PHP_METHOD(SoapServer, handle) sapi_add_header("Content-Type: text/xml; charset=utf-8", sizeof("Content-Type: text/xml; charset=utf-8")-1, 1); } - if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0)) { + if (INI_INT("zlib.output_compression")) { sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1); } else { snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size); @@ -1676,7 +1676,7 @@ static void soap_server_fault_ex(sdlFunctionPtr function, zval* fault, soapHeade if (use_http_error_status) { sapi_add_header("HTTP/1.1 500 Internal Server Error", sizeof("HTTP/1.1 500 Internal Server Error")-1, 1); } - if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0)) { + if (INI_INT("zlib.output_compression")) { sapi_add_header("Connection: close", sizeof("Connection: close")-1, 1); } else { snprintf(cont_len, sizeof(cont_len), "Content-Length: %d", size);