Commit a437eab2f68 for php.net
commit a437eab2f68df60e6c51199fa9579c58e7eeeb3e
Author: David Carlier <devnexen@gmail.com>
Date: Sat Jul 4 04:59:26 2026 +0100
ext/soap: fix use of uninitialized params in do_request() on OOM bailout.
Fix #22585
close GH-22586
diff --git a/NEWS b/NEWS
index e5dd4913e58..3ed4f27a6ac 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 d4845873e68..a3e03e0fb58 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(¶ms[0]);
+ ZVAL_UNDEF(¶ms[1]);
+ ZVAL_UNDEF(¶ms[2]);
+
zend_try {
ZVAL_STRINGL(¶ms[0], buf, buf_size);
ZVAL_STRING(¶ms[1], location);
diff --git a/ext/soap/tests/gh22585.phpt b/ext/soap/tests/gh22585.phpt
new file mode 100644
index 00000000000..9d007d012b4
--- /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.*)