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