Commit 8dafaf5da2f for php.net
commit 8dafaf5da2f5fc1c332c1fd3c1ccb0f322d21c51
Author: Lazizbek Ergashev <lazerg2@gmail.com>
Date: Sun Aug 30 12:49:03 2026 +0100
Fix GH-23447: segfault when the SoapServer class fails to initialize
SoapServer::handle() ignored the return value of object_init_ex(), so when
the class given to setClass() could not be instantiated the code carried on
with a NULL zval and crashed on Z_OBJCE_P(soap_obj). That happens for
instance when a property default references an undefined constant, since
evaluating it throws an Error and object creation fails.
Now the failure is reported as a SOAP fault, the same way a throwing
constructor already is.
Close GH-23448
diff --git a/NEWS b/NEWS
index 519b0ccaf05..04adab59625 100644
--- a/NEWS
+++ b/NEWS
@@ -62,6 +62,10 @@ PHP NEWS
. Fixed bug GH-23477 (Memory leak on duplicate native Phar manifest entries).
(Weilin Du)
+- SOAP:
+ . Fixed bug GH-23447 (Segfault when a class passed to SoapServer::setClass()
+ fails to initialize). (Lazizbek Ergashev)
+
- Standard:
. Fixed a segfault when a stream filter callback unsets StreamBucket::$data
before re-attaching the bucket. (iliaal)
diff --git a/ext/soap/soap.c b/ext/soap/soap.c
index 3d5536ef862..4703c777930 100644
--- a/ext/soap/soap.c
+++ b/ext/soap/soap.c
@@ -1478,7 +1478,11 @@ PHP_METHOD(SoapServer, handle)
/* If new session or something weird happned */
if (soap_obj == NULL) {
- object_init_ex(&tmp_soap, service->soap_class.ce);
+ if (UNEXPECTED(object_init_ex(&tmp_soap, service->soap_class.ce) != SUCCESS)) {
+ php_output_discard();
+ _soap_server_exception(service, function, ZEND_THIS);
+ goto fail;
+ }
/* Call constructor */
if (service->soap_class.ce->constructor) {
diff --git a/ext/soap/tests/gh23447.phpt b/ext/soap/tests/gh23447.phpt
new file mode 100644
index 00000000000..16ecc4568eb
--- /dev/null
+++ b/ext/soap/tests/gh23447.phpt
@@ -0,0 +1,28 @@
+--TEST--
+GH-23447 (Segfault when a class passed to SoapServer::setClass() fails to initialize)
+--EXTENSIONS--
+soap
+--CREDITS--
+Lu Maltsis (@lmaltsis)
+--FILE--
+<?php
+class foo {
+ private $broken = undefinedConstant;
+}
+
+$server = new SoapServer(null, ['uri' => 'http://testuri.org']);
+$server->setClass('foo');
+
+$server->handle(<<<'XML'
+<?xml version="1.0"?>
+<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
+ <SOAP-ENV:Body><anything/></SOAP-ENV:Body>
+</SOAP-ENV:Envelope>
+XML);
+
+echo "ok\n";
+?>
+--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>Undefined constant "undefinedConstant"</faultstring></SOAP-ENV:Fault></SOAP-ENV:Body></SOAP-ENV:Envelope>
+ok