[php-src] master: Merge branch 'PHP-8.5'

Ilia Alshanetsky <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Ilia Alshanetsky (iliaal)
Date: 2026-08-30T12:14:28-04:00

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

Merge branch 'PHP-8.5'

* PHP-8.5:
  [SOAP] Fix WSDL cache corruption when header defines headerfaults

Changed paths:
  A  ext/soap/tests/headerfault_cache.phpt
  A  ext/soap/tests/headerfault_cache.wsdl
  M  NEWS
  M  ext/soap/php_sdl.c


Diff:

diff --git a/NEWS b/NEWS
index 2dd3d1275b5a..89a8dd8dc939 100644
--- a/NEWS
+++ b/NEWS
@@ -40,6 +40,10 @@ PHP                                                                        NEWS
     which detached the classic BPF filter instead of the reuseport program.
     (David Carlier)
 
+- SOAP:
+  . Fixed WSDL cache corruption when a soap:header defines headerfaults.
+    (Ilia Alshanetsky)
+
 - Standard:
   . Fixed a segfault when a stream filter callback unsets StreamBucket::$data
     before re-attaching the bucket. (iliaal)
diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c
index c6e53c408aa8..3062a2d4dbf6 100644
--- a/ext/soap/php_sdl.c
+++ b/ext/soap/php_sdl.c
@@ -1144,7 +1144,7 @@ static sdlPtr load_wsdl(zval *this_ptr, char *struri)
 	return ctx.sdl;
 }
 
-#define WSDL_CACHE_VERSION 0x10
+#define WSDL_CACHE_VERSION 0x11
 
 #define WSDL_CACHE_GET(ret,type,buf)   memcpy(&ret,*buf,sizeof(type)); *buf += sizeof(type);
 #define WSDL_CACHE_GET_INT(ret,buf)    ret = ((unsigned char)(*buf)[0])|((unsigned char)(*buf)[1]<<8)|((unsigned char)(*buf)[2]<<16)|((unsigned)(*buf)[3]<<24); *buf += 4;
@@ -2054,7 +2054,7 @@ static void sdl_serialize_soap_body(const sdlSoapBindingFunctionBodyPtr body, co
 				sdlSoapBindingFunctionHeaderPtr tmp2;
 				const zend_string *key_inner;
 
-				ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(body->headers, key_inner, tmp2) {
+				ZEND_HASH_MAP_FOREACH_STR_KEY_PTR(tmp->headerfaults, key_inner, tmp2) {
 					sdl_serialize_key(key_inner, out);
 					WSDL_CACHE_PUT_1(tmp2->use, out);
 					if (tmp2->use == SOAP_ENCODED) {
diff --git a/ext/soap/tests/headerfault_cache.phpt b/ext/soap/tests/headerfault_cache.phpt
new file mode 100644
index 000000000000..6da747902d80
--- /dev/null
+++ b/ext/soap/tests/headerfault_cache.phpt
@@ -0,0 +1,45 @@
+--TEST--
+WSDL cache corruption when soap:header has headerfaults
+--EXTENSIONS--
+soap
+--INI--
+soap.wsdl_cache_enabled=1
+--FILE--
+<?php
+$dir = __DIR__ . '/headerfault_cache_dir';
+@mkdir($dir);
+ini_set('soap.wsdl_cache_dir', $dir);
+
+$options = ['cache_wsdl' => WSDL_CACHE_DISK];
+
+$c1 = new SoapClient(__DIR__ . '/headerfault_cache.wsdl', $options);
+var_dump($c1->__getFunctions());
+
+$c2 = new SoapClient(__DIR__ . '/headerfault_cache.wsdl', $options);
+var_dump($c2->__getFunctions());
+
+echo "ok\n";
+?>
+--CLEAN--
+<?php
+$dir = __DIR__ . '/headerfault_cache_dir';
+if (is_dir($dir)) {
+    foreach (scandir($dir) as $f) {
+        if ($f === '.' || $f === '..') {
+            continue;
+        }
+        @unlink($dir . '/' . $f);
+    }
+    @rmdir($dir);
+}
+?>
+--EXPECT--
+array(1) {
+  [0]=>
+  string(32) "string testHeader(string $param)"
+}
+array(1) {
+  [0]=>
+  string(32) "string testHeader(string $param)"
+}
+ok
diff --git a/ext/soap/tests/headerfault_cache.wsdl b/ext/soap/tests/headerfault_cache.wsdl
new file mode 100644
index 000000000000..8a844c0b899d
--- /dev/null
+++ b/ext/soap/tests/headerfault_cache.wsdl
@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<wsdl:definitions xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://example.com/hf" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://example.com/hf">
+  <wsdl:message name="message">
+    <wsdl:part name="param" type="xsd:string"/>
+  </wsdl:message>
+  <wsdl:message name="authToken">
+    <wsdl:part name="authToken" type="xsd:string"/>
+  </wsdl:message>
+  <wsdl:message name="traceId">
+    <wsdl:part name="traceId" type="xsd:string"/>
+  </wsdl:message>
+  <wsdl:message name="faultToken">
+    <wsdl:part name="faultToken" type="xsd:string"/>
+  </wsdl:message>
+  <wsdl:message name="faultTrace">
+    <wsdl:part name="faultTrace" type="xsd:string"/>
+  </wsdl:message>
+  <wsdl:portType name="hf">
+    <wsdl:operation name="testHeader">
+      <wsdl:input message="tns:message"/>
+      <wsdl:output message="tns:message"/>
+    </wsdl:operation>
+  </wsdl:portType>
+  <wsdl:binding name="hfBinding" type="tns:hf">
+    <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
+    <wsdl:operation name="testHeader">
+      <soap:operation soapAction="http://example.com/hf/testHeader"/>
+      <wsdl:input>
+        <soap:body namespace="http://example.com/hf" use="literal"/>
+        <soap:header namespace="http://example.com/hf" use="literal" part="authToken" message="tns:authToken">
+          <soap:headerfault namespace="http://example.com/hf" use="literal" part="faultToken" message="tns:faultToken"/>
+        </soap:header>
+        <soap:header namespace="http://example.com/hf" use="literal" part="traceId" message="tns:traceId">
+          <soap:headerfault namespace="http://example.com/hf" use="literal" part="faultTrace" message="tns:faultTrace"/>
+        </soap:header>
+      </wsdl:input>
+      <wsdl:output>
+        <soap:body namespace="http://example.com/hf" use="literal"/>
+      </wsdl:output>
+    </wsdl:operation>
+  </wsdl:binding>
+  <wsdl:service name="hfService">
+    <wsdl:port binding="tns:hfBinding" name="hfPort">
+      <soap:address location="http://localhost/hf.php"/>
+    </wsdl:port>
+  </wsdl:service>
+</wsdl:definitions>
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.