Commit 0f779a67bb9 for php
commit 0f779a67bb999ff98b5c0ac947ded3aec70d1418
Author: ndossche <7771979+ndossche@users.noreply.github.com>
Date: Wed Nov 11 21:43:16 2026 +0100
Fix GH-25311: Assertion ret == SUCCESS in array_map()/array_filter() after delayed out-of-memory
diff --git a/NEWS b/NEWS
index 82567c5abf3..18b784ca064 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,8 @@ PHP NEWS
nested isset()/empty(). (Jorg Sowa)
. Fixed AST printing dropping readonly on promoted constructor parameters.
(Jorg Sowa)
+ . Fixed bug GH-25311 (Assertion ret == SUCCESS in array_map()/array_filter()
+ after delayed out-of-memory). (ndossche)
- Curl:
. Fixed curl_reset() retaining CURLOPT_PRIVATE after reset. (lacatoire)
diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c
index 01555e6165c..aeb68bdd6be 100644
--- a/Zend/zend_execute_API.c
+++ b/Zend/zend_execute_API.c
@@ -823,9 +823,11 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_
return FAILURE; /* executor is already inactive */
}
if (ZEND_HAS_OOM()) {
- /* Callers expect SUCCESS || EG(exception), so let's throw right now */
+ /* Throws UnwindExit if the OOM is pending. If not pending, acts as if executor is inactive. */
zend_handle_delayed_oom();
- return FAILURE;
+ if (!EG(exception)) {
+ return FAILURE;
+ }
}
if (EG(exception)) {
if (fci_cache) {
diff --git a/ext/standard/tests/array/gh25311.phpt b/ext/standard/tests/array/gh25311.phpt
new file mode 100644
index 00000000000..c41ad6d7343
--- /dev/null
+++ b/ext/standard/tests/array/gh25311.phpt
@@ -0,0 +1,14 @@
+--TEST--
+GH-25311 (Assertion ret == SUCCESS in array_map()/array_filter() after delayed out-of-memory)
+--INI--
+memory_limit=10M
+--FILE--
+<?php
+
+$s = str_repeat("a", 5 * 1024 * 1024);
+$s .= $s;
+array_map(fn($x) => $x, [1]);
+
+?>
+--EXPECTF--
+Fatal error: Allowed memory size of 10485760 bytes exhausted %s