diff --git a/NEWS b/NEWS index 9ed0c725969..5dd508ccafb 100644 --- a/NEWS +++ b/NEWS @@ -14,6 +14,7 @@ PHP NEWS - Curl: . Fix memory leaks when returning refcounted value from curl callback. (nielsdos) + . Remove incorrect string release. (nielsdos) - DOM: . Fixed bug GH-18979 (Dom\XMLDocument::createComment() triggers undefined @@ -40,6 +41,10 @@ PHP NEWS . Fixed bug GH-18958 (Fatal error during shutdown after pcntl_rfork() or pcntl_forkx() with zend-max-execution-timers). (Arnaud) +- SOAP: + . Fixed bug GH-18990, bug #81029, bug #47314 (SOAP HTTP socket not closing + on object destruction). (nielsdos) + - Standard: . Fix misleading errors in printf(). (nielsdos) . Fix RCN violations in array functions. (nielsdos) @@ -50,6 +55,9 @@ PHP NEWS . Fixed GH-13264 (fgets() and stream_get_line() do not return false on filter fatal error). (Jakub Zelenka) +- Zip: + . Fix leak when path is too long in ZipArchive::extractTo(). (nielsdos) + 03 Jul 2025, PHP 8.4.10 - BcMath: diff --git a/ext/curl/interface.c b/ext/curl/interface.c index efccb8c34d0..965e4971267 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -1390,7 +1390,6 @@ static inline CURLcode add_simple_field(curl_mime *mime, zend_string *string_key part = curl_mime_addpart(mime); if (part == NULL) { zend_tmp_string_release(tmp_postval); - zend_string_release_ex(string_key, 0); return CURLE_OUT_OF_MEMORY; } if ((form_error = curl_mime_name(part, ZSTR_VAL(string_key))) != CURLE_OK diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index a1bd7dff0c8..2a82f739ceb 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -506,9 +506,9 @@ try_again: zend_string_equals(orig->host, phpurl->host) && orig->port == phpurl->port))) { } else { + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr)); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); stream = NULL; use_proxy = 0; @@ -517,9 +517,9 @@ try_again: /* Check if keep-alive connection is still opened */ if (stream != NULL && php_stream_eof(stream)) { + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr)); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); stream = NULL; use_proxy = 0; @@ -528,9 +528,7 @@ try_again: if (!stream) { stream = http_connect(this_ptr, phpurl, use_ssl, context, &use_proxy); if (stream) { - php_stream_auto_cleanup(stream); - ZVAL_RES(Z_CLIENT_HTTPSOCKET_P(this_ptr), stream->res); - GC_ADDREF(stream->res); + php_stream_to_zval(stream, Z_CLIENT_HTTPSOCKET_P(this_ptr)); ZVAL_LONG(Z_CLIENT_USE_PROXY_P(this_ptr), use_proxy); } else { php_url_free(phpurl); @@ -686,9 +684,9 @@ try_again: if (UNEXPECTED(php_random_bytes_throw(&nonce, sizeof(nonce)) != SUCCESS)) { ZEND_ASSERT(EG(exception)); + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr)); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); smart_str_free(&soap_headers_z); smart_str_free(&soap_headers); @@ -904,9 +902,9 @@ try_again: if (request != buf) { zend_string_release_ex(request, 0); } + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr)); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); add_soap_fault(this_ptr, "HTTP", "Failed Sending HTTP SOAP request", NULL, NULL); smart_str_free(&soap_headers_z); @@ -929,8 +927,8 @@ try_again: if (request != buf) { zend_string_release_ex(request, 0); } + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); add_soap_fault(this_ptr, "HTTP", "Error Fetching http headers", NULL, NULL); smart_str_free(&soap_headers_z); @@ -982,11 +980,11 @@ try_again: if (request != buf) { zend_string_release_ex(request, 0); } + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); if (http_headers) { zend_string_release_ex(http_headers, 0); } - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); if (http_msg) { efree(http_msg); @@ -1117,9 +1115,9 @@ try_again: if (request != buf) { zend_string_release_ex(request, 0); } + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); zend_string_release_ex(http_headers, 0); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); add_soap_fault(this_ptr, "HTTP", "Error Fetching http body, No Content-Length, connection closed or chunked data", NULL, NULL); if (http_msg) { @@ -1134,8 +1132,8 @@ try_again: } if (http_close) { + ZVAL_NULL(Z_CLIENT_HTTPSOCKET_P(this_ptr)); php_stream_close(stream); - convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); stream = NULL; } diff --git a/ext/soap/tests/bugs/gh18990.phpt b/ext/soap/tests/bugs/gh18990.phpt new file mode 100644 index 00000000000..30dbc0fe8b7 --- /dev/null +++ b/ext/soap/tests/bugs/gh18990.phpt @@ -0,0 +1,58 @@ +--TEST-- +GH-18990 (SOAP HTTP socket not closing on object destruction) +--INI-- +soap.wsdl_cache_enabled=0 +--EXTENSIONS-- +soap +--SKIPIF-- + +text0text1text2text3text4text5text6text7text8text9 +EOF; + +$responses = [ + "data://text/plain,HTTP/1.1 200 OK\r\n". + "Content-Type: text/xml;charset=utf-8\r\n". + "Connection: Keep-Alive\r\n". + "Content-Length: ".strlen($wsdl)."\r\n". + "\r\n". + $wsdl, + + "data://text/plain,HTTP/1.1 200 OK\r\n". + "Content-Type: text/xml;charset=utf-8\r\n". + "Connection: Keep-Alive\r\n". + "Content-Length: ".strlen($soap)."\r\n". + "\r\n". + $soap, +]; + +['pid' => $pid, 'uri' => $uri] = http_server($responses); + +$options = [ + 'trace' => false, + 'location' => $uri, +]; + +$cnt = count(get_resources()); + +$client = new SoapClient($uri, $options); + +var_dump(count($client->getItems())); + +http_server_kill($pid); + +unset($client); +var_dump(count(get_resources()) - $cnt); +?> +--EXPECT-- +int(10) +int(0) diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 45c92abc114..3d70668be1f 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -217,6 +217,7 @@ static int php_zip_extract_file(struct zip * za, char *dest, const char *file, s return 0; } else if (len > MAXPATHLEN) { php_error_docref(NULL, E_WARNING, "Full extraction path exceed MAXPATHLEN (%i)", MAXPATHLEN); + efree(fullpath); efree(file_dirname_fullpath); zend_string_release_ex(file_basename, 0); CWD_STATE_FREE(new_state.cwd);