From b245e7ff0842bdb2bd97838543ddf57019ad70f0 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 14 Jun 2026 13:44:18 +0100 Subject: [PATCH 1/2] ext/soap: ignore empty SOAPAction header during server dispatch. Fix #22285 Since 8.5 SoapServer::handle() uses the HTTP SOAPAction header to select the operation, falling back to the request body otherwise. An empty header made every request match the first WSDL operation. Skip empty SOAPAction headers so dispatch falls back to body inspection. --- ext/soap/soap.c | 2 +- ext/soap/tests/bugs/gh22285.phpt | 45 +++++++++++++++ ext/soap/tests/bugs/gh22285.wsdl | 96 ++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 ext/soap/tests/bugs/gh22285.phpt create mode 100644 ext/soap/tests/bugs/gh22285.wsdl diff --git a/ext/soap/soap.c b/ext/soap/soap.c index b7ed44929872..2f51b6f61dea 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -1394,7 +1394,7 @@ PHP_METHOD(SoapServer, handle) } } - if ((soap_action_z = zend_hash_str_find(Z_ARRVAL_P(server_vars), ZEND_STRL("HTTP_SOAPACTION"))) != NULL && Z_TYPE_P(soap_action_z) == IS_STRING) { + if ((soap_action_z = zend_hash_str_find(Z_ARRVAL_P(server_vars), ZEND_STRL("HTTP_SOAPACTION"))) != NULL && Z_TYPE_P(soap_action_z) == IS_STRING && Z_STRLEN_P(soap_action_z) > 0) { soap_action = Z_STRVAL_P(soap_action_z); } } diff --git a/ext/soap/tests/bugs/gh22285.phpt b/ext/soap/tests/bugs/gh22285.phpt new file mode 100644 index 000000000000..8c7e0933588e --- /dev/null +++ b/ext/soap/tests/bugs/gh22285.phpt @@ -0,0 +1,45 @@ +--TEST-- +GH-22285 (SoapServer dispatches to the first function when the SOAPAction header is empty) +--CREDITS-- +Jarkko Hyvärinen +--EXTENSIONS-- +soap +--INI-- +soap.wsdl_cache_enabled=0 +--SKIPIF-- + +--POST-- + + + + World + + + +--FILE-- + 'Hello ' . $params->name]; + } + public function goodbye($params) { + return ['message' => 'Goodbye ' . $params->name]; + } +} + +$server = new SoapServer(__DIR__ . '/gh22285.wsdl', [ + 'cache_wsdl' => WSDL_CACHE_NONE, + 'encoding' => 'UTF-8', + 'soap_version' => SOAP_1_1, +]); +$server->setClass('TestWS'); +$_SERVER['HTTP_SOAPACTION'] = '""'; +$server->handle(); +?> +--EXPECTF-- + +Goodbye World diff --git a/ext/soap/tests/bugs/gh22285.wsdl b/ext/soap/tests/bugs/gh22285.wsdl new file mode 100644 index 000000000000..66b9e6749071 --- /dev/null +++ b/ext/soap/tests/bugs/gh22285.wsdl @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 85214324273884a18dacffbec2f9d52d3922bad1 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sun, 14 Jun 2026 13:47:29 +0100 Subject: [PATCH 2/2] add test and fix quoted empty strings case --- ext/soap/soap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/soap/soap.c b/ext/soap/soap.c index 2f51b6f61dea..2bb49ee4c8fb 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -3178,6 +3178,10 @@ static sdlFunctionPtr find_function_using_soap_action(const sdl *sdl, const char soap_action_length -= 2; } + if (UNEXPECTED(soap_action_length == 0)) { + return NULL; + } + /* TODO: This may depend on a particular target namespace, in which case this won't find a match when multiple different * target namespaces are used until #45282 is resolved. */ sdlFunctionPtr function;