Commit 1c4bf04783b for php.net
commit 1c4bf04783b4915a908a1f7f09a4f4fe2f115ed6
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Thu Jul 16 08:30:45 2026 -0400
ext/soap: fix NULL deref on malformed HTTP status line
make_http_soap_request() looked for the reason phrase with strstr(tmp, " ")
even when the first strstr() found no space, which happens for a status line
carrying a version but no status code, such as "HTTP/1.1". tmp is NULL there,
so strstr() dereferenced it and the client crashed.
Only parse the reason phrase when a status code field was present.
Closes GH-22761
diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c
index e9fd68007d2..125c9258200 100644
--- a/ext/soap/php_http.c
+++ b/ext/soap/php_http.c
@@ -956,14 +956,14 @@ int make_http_soap_request(zval *this_ptr,
if (tmp != NULL) {
tmp++;
http_status = atoi(tmp);
- }
- tmp = strstr(tmp," ");
- if (tmp != NULL) {
- tmp++;
- if (http_msg) {
- efree(http_msg);
+ tmp = strstr(tmp," ");
+ if (tmp != NULL) {
+ tmp++;
+ if (http_msg) {
+ efree(http_msg);
+ }
+ http_msg = estrdup(tmp);
}
- http_msg = estrdup(tmp);
}
efree(http_version);
diff --git a/ext/soap/tests/http_status_line_no_code.phpt b/ext/soap/tests/http_status_line_no_code.phpt
new file mode 100644
index 00000000000..de943571a49
--- /dev/null
+++ b/ext/soap/tests/http_status_line_no_code.phpt
@@ -0,0 +1,33 @@
+--TEST--
+SoapClient: malformed HTTP status line without status code must not crash
+--EXTENSIONS--
+soap
+--FILE--
+<?php
+$serverCode = <<<'CODE'
+$server = stream_socket_server("tcp://127.0.0.1:0", $errno, $errstr);
+phpt_notify_server_start($server);
+$conn = stream_socket_accept($server);
+while (($line = fgets($conn)) !== false) {
+ if ($line === "\r\n" || $line === "\n") {
+ break;
+ }
+}
+fwrite($conn, "HTTP/1.1\r\nContent-Type: text/xml\r\nContent-Length: 0\r\n\r\n");
+fclose($conn);
+CODE;
+
+$clientCode = <<<'CODE'
+$client = new SoapClient(null, [
+ 'location' => 'http://{{ ADDR }}',
+ 'uri' => 'http://testuri.org',
+ 'connection_timeout' => 3,
+]);
+var_dump($client->__doRequest('<x/>', 'http://{{ ADDR }}', 'T', 1));
+CODE;
+
+include sprintf('%s/../../openssl/tests/ServerClientTestCase.inc', __DIR__);
+ServerClientTestCase::getInstance()->run($clientCode, $serverCode);
+?>
+--EXPECT--
+string(0) ""