[php-src] master: ext/soap: fix use of uninitialized params in do_request() on OOM bailout.

David Carlier <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: David Carlier (devnexen)
Date: 2026-07-04T14:11:07+01:00

Commit: https://github.com/php/php-src/commit/a437eab2f68df60e6c51199fa9579c58e7eeeb3e
Raw diff: https://github.com/php/php-src/commit/a437eab2f68df60e6c51199fa9579c58e7eeeb3e.diff

ext/soap: fix use of uninitialized params in do_request() on OOM bailout.

Fix #22585

close GH-22586

Changed paths:
  A  ext/soap/tests/gh22585.phpt
  M  NEWS
  M  ext/soap/soap.c


Diff:

diff --git a/NEWS b/NEWS
index e5dd4913e580..3ed4f27a6ac1 100644
--- a/NEWS
+++ b/NEWS
@@ -42,6 +42,10 @@ PHP                                                                        NEWS
   . Fixed bug GH-21314 (Different session garbage collector behavior between
     PHP 8.3 and PHP 8.5). (jorgsowa)
 
+- SOAP:
+  . Fixed bug GH-22585 (OOM on bailout with uninitialized
+    do_request() parameters). (David Carlier)
+
 - Streams:
   . Fixed bug GH-21468 (Segfault in file_get_contents w/ a https URL
     and a proxy set). (CVE-2026-12184) (ndossche)
diff --git a/ext/soap/soap.c b/ext/soap/soap.c
index d4845873e689..a3e03e0fb58b 100644
--- a/ext/soap/soap.c
+++ b/ext/soap/soap.c
@@ -2333,6 +2333,10 @@ static bool do_request(zval *this_ptr, xmlDoc *request, const char *location, co
 		return false;
 	}
 
+	ZVAL_UNDEF(&params[0]);
+	ZVAL_UNDEF(&params[1]);
+	ZVAL_UNDEF(&params[2]);
+
 	zend_try {
 		ZVAL_STRINGL(&params[0], buf, buf_size);
 		ZVAL_STRING(&params[1], location);
diff --git a/ext/soap/tests/gh22585.phpt b/ext/soap/tests/gh22585.phpt
new file mode 100644
index 000000000000..9d007d012b44
--- /dev/null
+++ b/ext/soap/tests/gh22585.phpt
@@ -0,0 +1,39 @@
+--TEST--
+GH-22585 (Use of uninitialized params in do_request() on out-of-memory bailout)
+--EXTENSIONS--
+soap
+--INI--
+soap.wsdl_cache_enabled=0
+memory_limit=64M
+--FILE--
+<?php
+/* Deep recursion that keeps issuing SOAP calls until memory is exhausted while
+ * do_request() is only part-way through initializing its params array. The
+ * cleanup path must not touch the uninitialized slots. Depending on the
+ * environment the run ends either by the recursion limit (reaching "Done") or
+ * by the memory-exhaustion fatal; both are fine, a crash/UB abort is not. */
+try {
+    class MySoapClient extends SoapClient {
+        public function __doRequest($request, $location, $action, $version, $one_way = false, ?string $uriParserClass = null): string {
+            return '';
+        }
+    }
+
+    function main() {
+        for (;;) {
+            $soap = new MySoapClient(
+                null,
+                ['location' => "http://localhost/soap.php", 'uri' => "http://localhost/"]
+            );
+            $soap->call(1.1);
+            main();
+        }
+    }
+
+    main();
+} catch (\Throwable $e) {
+}
+echo "Done" . PHP_EOL;
+?>
+--EXPECTREGEX--
+(?s)(Done|.*Allowed memory size of \d+ bytes exhausted.*)
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.