Commit 3589066c7c0 for php
commit 3589066c7c0e0534d87925df3941045578fcaab1
Author: lazerg <lazerg2@gmail.com>
Date: Thu Nov 12 18:39:55 2026 +0000
Fix GH-25094: NULL dereference in SOAP get_doc_function() with missing parts
In document style, get_doc_function() walks the request Body elements
alongside the WSDL parts, but it never checks whether it ran out of elements.
When the Body has fewer elements than the operation declares, node becomes
NULL and the next part comparison dereferences it. Now it treats that as no
match, so the request gets the same "Procedure not present" fault as any
other mismatch.
Close GH-25101
diff --git a/NEWS b/NEWS
index b5dbe65a83c..4299e2d5fe2 100644
--- a/NEWS
+++ b/NEWS
@@ -83,6 +83,8 @@ PHP NEWS
- SOAP:
. Fixed bug GH-25267 (NULL dereference in to_xml_any() with integer key).
(lazerg)
+ . Fixed bug GH-25094 (NULL dereference in get_doc_function() with missing
+ parts). (lazerg)
- Readline:
. Fixed incorrect handling of non-ASCII pending_input bytes in readline_info(),
diff --git a/ext/soap/soap.c b/ext/soap/soap.c
index eb35cfc7265..3bba56782f3 100644
--- a/ext/soap/soap.c
+++ b/ext/soap/soap.c
@@ -4284,6 +4284,10 @@ static sdlFunctionPtr get_doc_function(sdlPtr sdl, xmlNodePtr params) /* {{{ */
xmlNodePtr node = params;
ZEND_HASH_FOREACH_PTR(tmp->requestParameters, param) {
+ if (node == NULL) {
+ ok = 0;
+ break;
+ }
if (param->element) {
if (strcmp(param->element->name, (char*)node->name) != 0) {
ok = 0;
diff --git a/ext/soap/tests/gh25094.phpt b/ext/soap/tests/gh25094.phpt
new file mode 100644
index 00000000000..59ad67d8789
--- /dev/null
+++ b/ext/soap/tests/gh25094.phpt
@@ -0,0 +1,29 @@
+--TEST--
+GH-25094 (NULL pointer dereference in get_doc_function() when the request has fewer parts than the WSDL)
+--CREDITS--
+cxxz16
+--EXTENSIONS--
+soap
+--INI--
+soap.wsdl_cache_enabled=0
+--FILE--
+<?php
+class TestService {
+ public function Test($a, $b) {
+ return $a;
+ }
+}
+
+$server = new SoapServer(__DIR__ . '/gh25094.wsdl');
+$server->setClass('TestService');
+
+$server->handle(<<<'XML'
+<?xml version="1.0"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://test-uri">
+ <SOAP-ENV:Body><tns:a>foo</tns:a></SOAP-ENV:Body>
+</SOAP-ENV:Envelope>
+XML);
+?>
+--EXPECT--
+<?xml version="1.0" encoding="UTF-8"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><SOAP-ENV:Fault><faultcode>SOAP-ENV:Server</faultcode><faultstring>Procedure 'a' not present</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
diff --git a/ext/soap/tests/gh25094.wsdl b/ext/soap/tests/gh25094.wsdl
new file mode 100644
index 00000000000..b7865b2db58
--- /dev/null
+++ b/ext/soap/tests/gh25094.wsdl
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns="http://schemas.xmlsoap.org/wsdl/"
+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:tns="http://test-uri"
+ targetNamespace="http://test-uri">
+ <types>
+ <xsd:schema targetNamespace="http://test-uri" elementFormDefault="qualified">
+ <xsd:element name="a" type="xsd:string"/>
+ <xsd:element name="b" type="xsd:string"/>
+ </xsd:schema>
+ </types>
+ <message name="TestRequest">
+ <part name="a" element="tns:a"/>
+ <part name="b" element="tns:b"/>
+ </message>
+ <message name="TestResponse">
+ <part name="r" element="tns:a"/>
+ </message>
+ <portType name="TestPortType">
+ <operation name="Test">
+ <input message="tns:TestRequest"/>
+ <output message="tns:TestResponse"/>
+ </operation>
+ </portType>
+ <binding name="TestBinding" type="tns:TestPortType">
+ <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+ <operation name="Test">
+ <soap:operation soapAction="http://test-uri/Test"/>
+ <input><soap:body use="literal"/></input>
+ <output><soap:body use="literal"/></output>
+ </operation>
+ </binding>
+ <service name="TestService">
+ <port name="TestPort" binding="tns:TestBinding">
+ <soap:address location="http://localhost/test"/>
+ </port>
+ </service>
+</definitions>