From 27c10ddce6302912a46d72a4dcd47c89f1209544 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Wed, 24 Jun 2026 07:34:59 -0400 Subject: [PATCH 1/9] soap: do not overwrite the parsed host on a protocol-relative redirect When a redirect Location is a protocol-relative reference (//host/path), php_url_parse() already fills new_url->host, but the scheme-less redirect handling overwrote it with a copy of the request host without releasing the parsed one. That leaks a zend_string per such redirect and pins the redirect back to the original host instead of the one the server named. Inherit host and port from the request URL only when new_url->host is NULL, mirroring the scheme guard directly above. Closes GH-22434 --- ext/soap/php_http.c | 6 ++- .../bugs/protocol_relative_redirect.phpt | 49 +++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 ext/soap/tests/bugs/protocol_relative_redirect.phpt diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 0bec42afbc37..e9fd68007d26 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -1151,8 +1151,10 @@ int make_http_soap_request(zval *this_ptr, zend_string_release_ex(http_body, 0); if (new_url->scheme == NULL && new_url->path != NULL) { new_url->scheme = phpurl->scheme ? zend_string_copy(phpurl->scheme) : NULL; - new_url->host = phpurl->host ? zend_string_copy(phpurl->host) : NULL; - new_url->port = phpurl->port; + if (new_url->host == NULL) { + new_url->host = phpurl->host ? zend_string_copy(phpurl->host) : NULL; + new_url->port = phpurl->port; + } if (new_url->path && ZSTR_VAL(new_url->path)[0] != '/') { if (phpurl->path) { char *t = ZSTR_VAL(phpurl->path); diff --git a/ext/soap/tests/bugs/protocol_relative_redirect.phpt b/ext/soap/tests/bugs/protocol_relative_redirect.phpt new file mode 100644 index 000000000000..e8f30ca66872 --- /dev/null +++ b/ext/soap/tests/bugs/protocol_relative_redirect.phpt @@ -0,0 +1,49 @@ +--TEST-- +SOAP client follows a protocol-relative (//host/path) redirect Location without leaking the host +--EXTENSIONS-- +soap +--SKIPIF-- + +--FILE-- +', + '', + 'ok', + ''; +} else { + http_response_code(302); + header("Location: //" . $_SERVER["HTTP_HOST"] . "/redirected"); +} +PHP; + +php_cli_server_start($code, null, $args); + +$client = new SoapClient(null, [ + 'location' => 'http://' . PHP_CLI_SERVER_ADDRESS . '/start', + 'uri' => 'test-uri', +]); + +try { + $client->__soapCall("foo", []); + echo "redirect followed\n"; +} catch (SoapFault $e) { + echo "SoapFault: " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +redirect followed From 1666d90b157e7dcc0d79be5f1743e61fb46f41af Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Thu, 25 Jun 2026 08:24:12 +0200 Subject: [PATCH 2/9] [ci skip] Update heading --- ext/bcmath/libbcmath/src/convert.c | 2 +- ext/bcmath/libbcmath/src/convert.h | 2 +- ext/dom/html5_parser.c | 2 +- ext/dom/html5_parser.h | 2 +- ext/dom/html5_serializer.c | 2 +- ext/dom/html5_serializer.h | 2 +- ext/dom/html_collection.c | 2 +- ext/dom/html_collection.h | 2 +- ext/dom/html_document.c | 2 +- ext/dom/infra.c | 2 +- ext/dom/infra.h | 2 +- ext/dom/inner_html_mixin.c | 2 +- ext/dom/internal_helpers.h | 2 +- ext/dom/lexbor/lexbor/core/swar.h | 2 +- ext/dom/lexbor/lexbor/selectors-adapted/selectors.c | 2 +- ext/dom/lexbor/lexbor/selectors-adapted/selectors.h | 2 +- ext/dom/namespace_compat.c | 2 +- ext/dom/namespace_compat.h | 2 +- ext/dom/nodelist.h | 2 +- ext/dom/parentnode/css_selectors.c | 2 +- ext/dom/parentnode/tree.c | 2 +- ext/dom/private_data.c | 2 +- ext/dom/private_data.h | 2 +- ext/dom/serialize_common.h | 2 +- ext/dom/token_list.c | 2 +- ext/dom/token_list.h | 2 +- ext/dom/xml_document.c | 2 +- ext/dom/xml_serializer.c | 2 +- ext/dom/xml_serializer.h | 2 +- ext/dom/xpath_callbacks.c | 2 +- ext/dom/xpath_callbacks.h | 2 +- ext/libxml/mime_sniff.c | 2 +- 32 files changed, 32 insertions(+), 32 deletions(-) diff --git a/ext/bcmath/libbcmath/src/convert.c b/ext/bcmath/libbcmath/src/convert.c index bf3d9a9a415b..056426a441e3 100644 --- a/ext/bcmath/libbcmath/src/convert.c +++ b/ext/bcmath/libbcmath/src/convert.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/bcmath/libbcmath/src/convert.h b/ext/bcmath/libbcmath/src/convert.h index 6ddd447c8048..f734f1821d3b 100644 --- a/ext/bcmath/libbcmath/src/convert.h +++ b/ext/bcmath/libbcmath/src/convert.h @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/html5_parser.c b/ext/dom/html5_parser.c index c00fa81b9c9e..34320a122f53 100644 --- a/ext/dom/html5_parser.c +++ b/ext/dom/html5_parser.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/html5_parser.h b/ext/dom/html5_parser.h index a56166639a60..76e60ea8c676 100644 --- a/ext/dom/html5_parser.h +++ b/ext/dom/html5_parser.h @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/html5_serializer.c b/ext/dom/html5_serializer.c index 26eef9d5f968..fc1202ef0e04 100644 --- a/ext/dom/html5_serializer.c +++ b/ext/dom/html5_serializer.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/html5_serializer.h b/ext/dom/html5_serializer.h index 27fd1c92f24f..c05d7d02a37b 100644 --- a/ext/dom/html5_serializer.h +++ b/ext/dom/html5_serializer.h @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/html_collection.c b/ext/dom/html_collection.c index e4c044601668..ca3edaba481a 100644 --- a/ext/dom/html_collection.c +++ b/ext/dom/html_collection.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/html_collection.h b/ext/dom/html_collection.h index a94daa1aae80..dfc4aba5b73a 100644 --- a/ext/dom/html_collection.h +++ b/ext/dom/html_collection.h @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/html_document.c b/ext/dom/html_document.c index 248e85c74c39..2e4740f7372b 100644 --- a/ext/dom/html_document.c +++ b/ext/dom/html_document.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/infra.c b/ext/dom/infra.c index eb276d179464..9a0478f193b8 100644 --- a/ext/dom/infra.c +++ b/ext/dom/infra.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/infra.h b/ext/dom/infra.h index d84ad5a2a0ef..59700ce10129 100644 --- a/ext/dom/infra.h +++ b/ext/dom/infra.h @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/inner_html_mixin.c b/ext/dom/inner_html_mixin.c index 0af47e2cf019..19f640e6b4ac 100644 --- a/ext/dom/inner_html_mixin.c +++ b/ext/dom/inner_html_mixin.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/internal_helpers.h b/ext/dom/internal_helpers.h index c87ea49c6143..c741b2fbeda1 100644 --- a/ext/dom/internal_helpers.h +++ b/ext/dom/internal_helpers.h @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/lexbor/lexbor/core/swar.h b/ext/dom/lexbor/lexbor/core/swar.h index ec0a13b8e23f..78579ad4bee7 100644 --- a/ext/dom/lexbor/lexbor/core/swar.h +++ b/ext/dom/lexbor/lexbor/core/swar.h @@ -1,7 +1,7 @@ /* * Copyright (C) 2024 Alexander Borisov * - * Author: Niels Dossche + * Author: Nora Dossche */ #ifndef LEXBOR_SWAR_H diff --git a/ext/dom/lexbor/lexbor/selectors-adapted/selectors.c b/ext/dom/lexbor/lexbor/selectors-adapted/selectors.c index 26e6f333fa8a..3f16ccfa5f5a 100644 --- a/ext/dom/lexbor/lexbor/selectors-adapted/selectors.c +++ b/ext/dom/lexbor/lexbor/selectors-adapted/selectors.c @@ -2,7 +2,7 @@ * Copyright (C) 2021-2026 Alexander Borisov * * Author: Alexander Borisov - * Adapted for PHP + libxml2 by: Niels Dossche + * Adapted for PHP + libxml2 by: Nora Dossche * Based on Lexbor (upstream commit 5291cde0d40f77e7c4ea364b7cd726269e0bf1f9) */ diff --git a/ext/dom/lexbor/lexbor/selectors-adapted/selectors.h b/ext/dom/lexbor/lexbor/selectors-adapted/selectors.h index b64a9e49ee26..b349b24a80b0 100644 --- a/ext/dom/lexbor/lexbor/selectors-adapted/selectors.h +++ b/ext/dom/lexbor/lexbor/selectors-adapted/selectors.h @@ -2,7 +2,7 @@ * Copyright (C) 2021-2025 Alexander Borisov * * Author: Alexander Borisov - * Adapted for PHP libxml2 by: Niels Dossche + * Adapted for PHP libxml2 by: Nora Dossche */ diff --git a/ext/dom/namespace_compat.c b/ext/dom/namespace_compat.c index e1dcd73503ea..d7fc86237b6b 100644 --- a/ext/dom/namespace_compat.c +++ b/ext/dom/namespace_compat.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/namespace_compat.h b/ext/dom/namespace_compat.h index 23c80acc7fd7..55efca381a12 100644 --- a/ext/dom/namespace_compat.h +++ b/ext/dom/namespace_compat.h @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/nodelist.h b/ext/dom/nodelist.h index 5ac3de1e46c4..8c1b9101ab0c 100644 --- a/ext/dom/nodelist.h +++ b/ext/dom/nodelist.h @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/parentnode/css_selectors.c b/ext/dom/parentnode/css_selectors.c index b215dc90039c..37f9d698e856 100644 --- a/ext/dom/parentnode/css_selectors.c +++ b/ext/dom/parentnode/css_selectors.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/parentnode/tree.c b/ext/dom/parentnode/tree.c index 9fb682910f07..81e260ee038d 100644 --- a/ext/dom/parentnode/tree.c +++ b/ext/dom/parentnode/tree.c @@ -11,7 +11,7 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Benjamin Eberlei | - | Niels Dossche | + | Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/private_data.c b/ext/dom/private_data.c index bb20093b8ebb..66b3f4f87f29 100644 --- a/ext/dom/private_data.c +++ b/ext/dom/private_data.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/private_data.h b/ext/dom/private_data.h index ead6c75caf24..109f06c90502 100644 --- a/ext/dom/private_data.h +++ b/ext/dom/private_data.h @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/serialize_common.h b/ext/dom/serialize_common.h index ed967c98a9ee..c2a37e4b98bc 100644 --- a/ext/dom/serialize_common.h +++ b/ext/dom/serialize_common.h @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/token_list.c b/ext/dom/token_list.c index fe768e17b2e9..14d310cd5a70 100644 --- a/ext/dom/token_list.c +++ b/ext/dom/token_list.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/token_list.h b/ext/dom/token_list.h index 4711852c4d87..bfe49a644e74 100644 --- a/ext/dom/token_list.h +++ b/ext/dom/token_list.h @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/xml_document.c b/ext/dom/xml_document.c index 4d941de0f068..ad7f3e9497fd 100644 --- a/ext/dom/xml_document.c +++ b/ext/dom/xml_document.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/xml_serializer.c b/ext/dom/xml_serializer.c index 7684057a391c..5e6a6f93b91c 100644 --- a/ext/dom/xml_serializer.c +++ b/ext/dom/xml_serializer.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/xml_serializer.h b/ext/dom/xml_serializer.h index 2d5c3bd84277..a129785042ea 100644 --- a/ext/dom/xml_serializer.h +++ b/ext/dom/xml_serializer.h @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/xpath_callbacks.c b/ext/dom/xpath_callbacks.c index 0bd6c3f33189..28a5272a302a 100644 --- a/ext/dom/xpath_callbacks.c +++ b/ext/dom/xpath_callbacks.c @@ -12,7 +12,7 @@ +----------------------------------------------------------------------+ | Authors: Christian Stocker | | Rob Richards | - | Niels Dossche | + | Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/dom/xpath_callbacks.h b/ext/dom/xpath_callbacks.h index 3a4d8731f474..80c2ee8b740d 100644 --- a/ext/dom/xpath_callbacks.h +++ b/ext/dom/xpath_callbacks.h @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ diff --git a/ext/libxml/mime_sniff.c b/ext/libxml/mime_sniff.c index 2840c69701fc..caed6c34d1e7 100644 --- a/ext/libxml/mime_sniff.c +++ b/ext/libxml/mime_sniff.c @@ -10,7 +10,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Niels Dossche | + | Authors: Nora Dossche | +----------------------------------------------------------------------+ */ From c8626dd3d3ae3dc1be5d0d506823c9cab6e3d93d Mon Sep 17 00:00:00 2001 From: Jarne Clauw <67628242+JarneClauw@users.noreply.github.com> Date: Thu, 25 Jun 2026 08:33:06 +0200 Subject: [PATCH 3/9] Fixing memory leak in openssl_x509_parse when str_serial creation fails (#21751) --- ext/openssl/openssl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 1689662f07a3..2c5a93c89925 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -2169,6 +2169,7 @@ PHP_FUNCTION(openssl_x509_parse) str_serial = i2s_ASN1_INTEGER(NULL, asn1_serial); /* Can return NULL on error or memory allocation failure */ if (!str_serial) { + OPENSSL_free(hex_serial); php_openssl_store_errors(); goto err; } From 42c392c5781fd527bb1720c4ed6a4254c28b0ad8 Mon Sep 17 00:00:00 2001 From: Nora Dossche <7771979+ndossche@users.noreply.github.com> Date: Thu, 25 Jun 2026 08:33:17 +0200 Subject: [PATCH 4/9] openssl: Use proper error propagation when X509_dup() fails in openssl_x509_read() (#21953) Otherwise x509 field is NULL and can cause a NULL deref which is UB (and causes a SEGV). --- ext/openssl/openssl.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 2c5a93c89925..cd16db03b8d0 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -2518,9 +2518,20 @@ PHP_FUNCTION(openssl_x509_read) RETURN_FALSE; } + X509 *obj_x509; + if (cert_obj) { + obj_x509 = X509_dup(cert); + if (!obj_x509) { + php_error_docref(NULL, E_WARNING, "X.509 Certificate could not be duplicated"); + RETURN_FALSE; + } + } else { + obj_x509 = cert; + } + object_init_ex(return_value, php_openssl_certificate_ce); x509_cert_obj = Z_OPENSSL_CERTIFICATE_P(return_value); - x509_cert_obj->x509 = cert_obj ? X509_dup(cert) : cert; + x509_cert_obj->x509 = obj_x509; } /* }}} */ From 22a2c2ed2f8efeb20aa913800665271dffa1bd13 Mon Sep 17 00:00:00 2001 From: Weilin Du Date: Thu, 25 Jun 2026 14:37:20 +0800 Subject: [PATCH 5/9] Zend: Introduce inline helpers for raw C-string concatenation (#21607) This commit introduces three new zend_always_inline helpers to Zend/zend_string.hfor concatenating raw C strings (char *), which is discussed before in #21597. - zend_str_append_char_to_raw - zend_str_concat_to_raw - zend_str_concat3_to_raw Now, several places in the codebase has manual emalloc + memcpy + \0 boilerplate to generate temporary char *. This manual approach is verbose, and harder to read. In some cases when we actually need a zend_string instead of char *, we already has some refactors (#21564 and #21567) by using zend_string_concat* API, but when it comes to char *, the API forces a 24-byte struct allocation, which is immediately discarded, and will unnecessarily lower performance. In order to solve this, I think we can introduce three APIs focusing on dealing with chars * refactoring. --- Zend/zend_string.h | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Zend/zend_string.h b/Zend/zend_string.h index 930d733307f4..971902cabd2b 100644 --- a/Zend/zend_string.h +++ b/Zend/zend_string.h @@ -22,8 +22,14 @@ #include "zend_gc.h" #include "zend_alloc.h" +#include "zend_errors.h" + BEGIN_EXTERN_C() +ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3); + +#include "zend_multiply.h" + typedef void (*zend_string_copy_storage_func_t)(void); typedef zend_string *(ZEND_FASTCALL *zend_new_interned_string_func_t)(zend_string *str); typedef zend_string *(ZEND_FASTCALL *zend_string_init_interned_func_t)(const char *str, size_t size, bool permanent); @@ -331,6 +337,48 @@ static zend_always_inline zend_string *zend_string_safe_realloc(zend_string *s, return ret; } +static zend_always_inline char *zend_cstr_append_char(const char *str, size_t len, char c) { + char *res = (char *)safe_emalloc(len, 1, 2); + if (len > 0) { + memcpy(res, str, len); + } + res[len] = c; + res[len + 1] = '\0'; + return res; +} + +static zend_always_inline char *zend_cstr_concat(const char *s1, size_t len1, const char *s2, size_t len2) { + size_t size = zend_safe_address_guarded(1, len1, len2); + size = zend_safe_address_guarded(1, size, 1); + char *res = (char *)emalloc(size); + if (len1 > 0) { + memcpy(res, s1, len1); + } + if (len2 > 0) { + memcpy(res + len1, s2, len2); + } + res[len1 + len2] = '\0'; + return res; +} + +static zend_always_inline char *zend_cstr_concat3(const char *s1, size_t len1, const char *s2, size_t len2, const char *s3, size_t len3) { + size_t size = zend_safe_address_guarded(1, len1, len2); + size = zend_safe_address_guarded(1, size, len3); + size = zend_safe_address_guarded(1, size, 1); + char *res = (char *)emalloc(size); + if (len1 > 0) { + memcpy(res, s1, len1); + } + if (len2 > 0) { + memcpy(res + len1, s2, len2); + } + if (len3 > 0) { + memcpy(res + len1 + len2, s3, len3); + } + res[len1 + len2 + len3] = '\0'; + return res; +} + static zend_always_inline void zend_string_free(zend_string *s) { if (!ZSTR_IS_INTERNED(s)) { From 8204d4b5db7f69c5f36fe1c9c7b3b1cd19be1332 Mon Sep 17 00:00:00 2001 From: Jarne Clauw <67628242+JarneClauw@users.noreply.github.com> Date: Thu, 25 Jun 2026 09:07:09 +0200 Subject: [PATCH 6/9] Fixing memory leak in openssl_pkcs12_read when zout initialisation fails (#21752) * Fixing memory leak * Simplified cleanup and adding test --- ext/openssl/openssl.c | 1 + .../tests/openssl_pkcs12_read_array_init.phpt | 23 +++++++++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 ext/openssl/tests/openssl_pkcs12_read_array_init.phpt diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index cd16db03b8d0..36d5a7ccb73c 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -2859,6 +2859,7 @@ PHP_FUNCTION(openssl_pkcs12_read) zout = zend_try_array_init(zout); if (!zout) { + sk_X509_pop_free(ca, X509_free); goto cleanup; } diff --git a/ext/openssl/tests/openssl_pkcs12_read_array_init.phpt b/ext/openssl/tests/openssl_pkcs12_read_array_init.phpt new file mode 100644 index 000000000000..b57cd32b686a --- /dev/null +++ b/ext/openssl/tests/openssl_pkcs12_read_array_init.phpt @@ -0,0 +1,23 @@ +--TEST-- +Memory leak when array initialization in openssl_pkcs12_read() fails +--EXTENSIONS-- +openssl +--FILE-- +foo, "csos"); +} catch (TypeError $e) { + echo $e::class, ": ", $e->getMessage(), "\n"; +} +?> +--EXPECT-- +TypeError: Cannot assign array to reference held by property Typed::$foo of type string From 997ad8730443cf3e6fbe290484244b22f9ce980a Mon Sep 17 00:00:00 2001 From: Jarne Clauw <67628242+JarneClauw@users.noreply.github.com> Date: Thu, 25 Jun 2026 09:07:15 +0200 Subject: [PATCH 7/9] Fixing memory leak in php_openssl_x509_fingerprint when getting mdtype with php_openssl_get_evp_md_by_name (#21965) --- ext/openssl/openssl_backend_common.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c index dddad4a00248..e5f1dbd67be9 100644 --- a/ext/openssl/openssl_backend_common.c +++ b/ext/openssl/openssl_backend_common.c @@ -597,6 +597,7 @@ zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool r php_error_docref(NULL, E_WARNING, "Unknown digest algorithm"); return NULL; } else if (!X509_digest(peer, mdtype, md, &n)) { + php_openssl_release_evp_md(mdtype); php_openssl_store_errors(); php_error_docref(NULL, E_ERROR, "Could not generate signature"); return NULL; @@ -610,6 +611,7 @@ zend_string* php_openssl_x509_fingerprint(X509 *peer, const char *method, bool r ZSTR_VAL(ret)[n * 2] = '\0'; } + php_openssl_release_evp_md(mdtype); return ret; } From 53d082e6eefffa901d6d3bccdaea6bb1ffa98f79 Mon Sep 17 00:00:00 2001 From: Jarne Clauw <67628242+JarneClauw@users.noreply.github.com> Date: Thu, 25 Jun 2026 09:07:34 +0200 Subject: [PATCH 8/9] Fixing memory leak in zif_openssl_seal and zif_openssl_open when fetching cipher with php_openssl_get_evp_cipher_by_name (#21967) --- ext/openssl/openssl.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index db811d4e7ed9..b8bb42e0aebc 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -4273,6 +4273,7 @@ PHP_FUNCTION(openssl_seal) iv_len = EVP_CIPHER_iv_length(cipher); if (!iv && iv_len > 0) { + php_openssl_release_evp_cipher(cipher); zend_argument_value_error(6, "cannot be null for the chosen cipher algorithm"); RETURN_THROWS(); } @@ -4359,6 +4360,7 @@ PHP_FUNCTION(openssl_seal) efree(eks); efree(eksl); efree(pkeys); + php_openssl_release_evp_cipher(cipher); } /* }}} */ @@ -4435,6 +4437,7 @@ PHP_FUNCTION(openssl_open) EVP_CIPHER_CTX_free(ctx); out_pkey: EVP_PKEY_free(pkey); + php_openssl_release_evp_cipher(cipher); } /* }}} */ From eeb02a0f14033ace9ac766028b14c29cda5e1cca Mon Sep 17 00:00:00 2001 From: Arshid Date: Thu, 25 Jun 2026 13:33:35 +0530 Subject: [PATCH 9/9] ext/Reflection: Simplify ReflectionClass::hasConstant() (#22438) --- ext/reflection/php_reflection.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index a208741b1590..f5b1cb2010a0 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -4762,11 +4762,7 @@ ZEND_METHOD(ReflectionClass, hasConstant) } GET_REFLECTION_OBJECT_PTR(ce); - if (zend_hash_exists(&ce->constants_table, name)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + RETURN_BOOL(zend_hash_exists(&ce->constants_table, name)); } /* }}} */