From d3af7240d9a81ff729b6208958df63c109cfa811 Mon Sep 17 00:00:00 2001 From: Shivam Mathur Date: Wed, 5 Aug 2026 12:27:48 +0530 Subject: [PATCH 1/4] Fix hMailServer URL in Windows CI (#23055) --- .github/scripts/windows/test_task.bat | 5 +++-- ext/standard/tests/mail/bug80751.phpt | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/scripts/windows/test_task.bat b/.github/scripts/windows/test_task.bat index 0bfdaf664125..199a23430f5c 100644 --- a/.github/scripts/windows/test_task.bat +++ b/.github/scripts/windows/test_task.bat @@ -116,8 +116,9 @@ set PHP_BUILD_DIR=%PHP_BUILD_OBJ_DIR%\Release if "%THREAD_SAFE%" equ "1" set PHP_BUILD_DIR=%PHP_BUILD_DIR%_TS rem prepare for mail -curl -sLo hMailServer.exe https://www.hmailserver.com/download_file/?downloadid=271 -hMailServer.exe /verysilent +curl -sLo hMailServer.zip https://downloads.php.net/~windows/php-sdk/deps/vs18/x64/hmailserver-5.7.0-vs18-x64.zip +unzip -q hMailServer.zip -d hMailServer +hMailServer\bin\hMailServer.exe /verysilent cd %APPVEYOR_BUILD_FOLDER% %PHP_BUILD_DIR%\php.exe -dextension_dir=%PHP_BUILD_DIR% -dextension=com_dotnet appveyor\setup_hmailserver.php diff --git a/ext/standard/tests/mail/bug80751.phpt b/ext/standard/tests/mail/bug80751.phpt index fd4fa744fe3c..97cb0575f82d 100644 --- a/ext/standard/tests/mail/bug80751.phpt +++ b/ext/standard/tests/mail/bug80751.phpt @@ -37,7 +37,7 @@ function find_and_delete_message($username, $subject) { if ($info->subject === $subject) { $header = imap_fetchheader($imap_stream, $i); echo "Return-Path header found: "; - var_dump(strpos($header, 'Return-Path: joe@example.com') !== false); + var_dump(strpos($header, 'Return-Path: ') !== false); echo "To header found: "; var_dump(strpos($header, "To: \"\" <{$users[1]}@$domain>") !== false); echo "From header found: "; From a0336012739b35630a32674a484a7023433bde27 Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 4 Aug 2026 20:58:56 +0200 Subject: [PATCH 2/4] session: fix corruption in mod_mm --- ext/session/mod_mm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/session/mod_mm.c b/ext/session/mod_mm.c index b997a2bdcff5..75ee713e9f09 100644 --- a/ext/session/mod_mm.c +++ b/ext/session/mod_mm.c @@ -351,7 +351,7 @@ PS_READ_FUNC(mm) && ps_mm_key_exists(data, key) == FAILURE) { /* key points to PS(id), but cannot change here. */ if (key) { - efree(PS(id)); + zend_string_release_ex(PS(id), false); PS(id) = NULL; } PS(id) = PS(mod)->s_create_sid((void **)&data); From 9366c61247f797e611a09f14478fc75a0b4edd33 Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Tue, 4 Aug 2026 21:00:40 +0200 Subject: [PATCH 3/4] Fix GH-23043: broken session id code can cause zend_mm_heap corrupted The id must be reset to NULL before calling code that can invoke userland code, as the id remains visible after release due to a stale pointer. Closes GH-23046. --- NEWS | 5 +++ ext/session/session.c | 3 ++ .../tests/user_session_module/gh23043.phpt | 35 +++++++++++++++++++ 3 files changed, 43 insertions(+) create mode 100644 ext/session/tests/user_session_module/gh23043.phpt diff --git a/NEWS b/NEWS index 378643836c80..474db936ef15 100644 --- a/NEWS +++ b/NEWS @@ -37,6 +37,11 @@ PHP NEWS . Fixed segfault in ReflectionMethod::createFromMethodName() on an uninstantiable subclass. (iliaal) +- Session: + . Fix corruption in mod_mm. (ndossche) + . Fixed bug GH-23043 (broken session id code can cause zend_mm_heap + corrupted). (ndossche) + - Sockets: . Fixed various memory related issues in ext/sockets. (David Carlier) diff --git a/ext/session/session.c b/ext/session/session.c index ba71d709a536..6380505ae951 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -443,6 +443,7 @@ static zend_result php_session_initialize(void) /* {{{ */ if (!PS(id) || !ZSTR_VAL(PS(id))[0]) { if (PS(id)) { zend_string_release_ex(PS(id), 0); + PS(id) = NULL; } PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); if (!PS(id)) { @@ -460,6 +461,7 @@ static zend_result php_session_initialize(void) /* {{{ */ ) { if (PS(id)) { zend_string_release_ex(PS(id), 0); + PS(id) = NULL; } PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); if (!PS(id)) { @@ -2440,6 +2442,7 @@ PHP_FUNCTION(session_regenerate_id) /* Try to generate non-existing ID */ while (limit-- && PS(mod)->s_validate_sid(&PS(mod_data), PS(id)) == SUCCESS) { zend_string_release_ex(PS(id), 0); + PS(id) = NULL; PS(id) = PS(mod)->s_create_sid(&PS(mod_data)); if (!PS(id)) { PS(mod)->s_close(&PS(mod_data)); diff --git a/ext/session/tests/user_session_module/gh23043.phpt b/ext/session/tests/user_session_module/gh23043.phpt new file mode 100644 index 000000000000..e3528884a79a --- /dev/null +++ b/ext/session/tests/user_session_module/gh23043.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-23043 (broken session id code can cause zend_mm_heap corrupted) +--EXTENSIONS-- +session +--CREDITS-- +lmaltsis +--FILE-- + +--EXPECTF-- +string(0) "" + +Warning: SessionHandler::write(): Session ID is too long or contains illegal characters. Only the A-Z, a-z, 0-9, "-", and "," characters are allowed in %s on line %d + +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: a::write) in %s on line %d +string(0) "" + +Warning: SessionHandler::write(): Session ID is too long or contains illegal characters. Only the A-Z, a-z, 0-9, "-", and "," characters are allowed in Unknown on line 0 + +Warning: session_write_close(): Failed to write session data using user defined save handler. (session.save_path: , handler: a::write) in Unknown on line 0 From 0094ebf7778eb52fd95aac68f34d360bdcad01e9 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Wed, 5 Aug 2026 09:16:11 -0400 Subject: [PATCH 4/4] Fix segfault comparing uninitialized SimpleXMLElement instances sxe_objects_compare dereferenced document->ptr when both nodes were NULL without checking document. A subclass that skips parent __construct leaves document NULL, so $a == $b segfaulted. Treat two NULL documents as equal and mixed NULL/non-NULL as uncomparable. Closes GH-23067 --- NEWS | 4 +++ ext/simplexml/simplexml.c | 6 +++++ .../tests/bug_sxe_compare_uninitialized.phpt | 25 +++++++++++++++++++ 3 files changed, 35 insertions(+) create mode 100644 ext/simplexml/tests/bug_sxe_compare_uninitialized.phpt diff --git a/NEWS b/NEWS index 474db936ef15..a9ca3fea246c 100644 --- a/NEWS +++ b/NEWS @@ -42,6 +42,10 @@ PHP NEWS . Fixed bug GH-23043 (broken session id code can cause zend_mm_heap corrupted). (ndossche) +- SimpleXML: + . Fixed segfault when comparing uninitialized SimpleXMLElement + instances. (iliaal) + - Sockets: . Fixed various memory related issues in ext/sockets. (David Carlier) diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 8cf8e657e58f..b3266f813975 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1229,6 +1229,12 @@ static int sxe_objects_compare(zval *object1, zval *object2) /* {{{ */ if (sxe1->node == NULL && sxe2->node == NULL) { /* Both nodes not set: Only support equality comparison between documents. */ + if (sxe1->document == NULL || sxe2->document == NULL) { + if (sxe1->document == sxe2->document) { + return 0; + } + return ZEND_UNCOMPARABLE; + } if (sxe1->document->ptr == sxe2->document->ptr) { return 0; } diff --git a/ext/simplexml/tests/bug_sxe_compare_uninitialized.phpt b/ext/simplexml/tests/bug_sxe_compare_uninitialized.phpt new file mode 100644 index 000000000000..742761eed6c0 --- /dev/null +++ b/ext/simplexml/tests/bug_sxe_compare_uninitialized.phpt @@ -0,0 +1,25 @@ +--TEST-- +Comparing uninitialized SimpleXMLElement instances must not segfault +--EXTENSIONS-- +simplexml +--FILE-- +'); +echo "uninit vs init: "; +var_dump($a == $c); +echo "done\n"; +?> +--EXPECT-- +equal: bool(true) +identical: bool(false) +uninit vs init: bool(false) +done