From 7771ec07e5cb00f2400055fa5d2d08af4bc92809 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 8 Sep 2024 00:06:22 +0200 Subject: [PATCH] Fix bug #61525: SOAP functions require at least one space after HTTP header colon HTTP/1.1 does not require a single whitespace after the colon, and SoapServer does implement HTTP/1.1. The header value is already correctly whitespace-trimmed, so no behaviour change happens w.r.t. header values. Closes GH-15793. --- NEWS | 4 ++++ ext/soap/php_http.c | 24 +++++++++++----------- ext/soap/tests/bugs/bug61525.phpt | 33 +++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 ext/soap/tests/bugs/bug61525.phpt diff --git a/NEWS b/NEWS index 65a0a1c1d4f..1a2422c653f 100644 --- a/NEWS +++ b/NEWS @@ -49,6 +49,10 @@ PHP NEWS . Fixed bug GH-15718 (Segfault on ReflectionProperty::get{Hook,Hooks}() on dynamic properties). (DanielEScherzer) +- SOAP: + . Fixed bug #61525 (SOAP functions require at least one space after HTTP + header colon). (nielsdos) + - Standard: . Fixed bug GH-15552 (Signed integer overflow in ext/standard/scanf.c). (cmb) . Implemented GH-15685 (improve proc_open error reporting on Windows). (cmb) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 60e8044a825..bd548b5b303 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -980,7 +980,7 @@ try_again: */ cookie_itt = ZSTR_VAL(http_headers); - while ((cookie_itt = get_http_header_value_nodup(cookie_itt, "Set-Cookie: ", &cookie_len))) { + while ((cookie_itt = get_http_header_value_nodup(cookie_itt, "Set-Cookie:", &cookie_len))) { zval *cookies = Z_CLIENT_COOKIES_P(this_ptr); SEPARATE_ARRAY(cookies); @@ -1049,7 +1049,7 @@ try_again: if (http_1_1) { http_close = FALSE; if (use_proxy && !use_ssl) { - connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection: "); + connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection:"); if (connection) { if (strncasecmp(connection, "close", sizeof("close")-1) == 0) { http_close = TRUE; @@ -1058,7 +1058,7 @@ try_again: } } if (http_close == FALSE) { - connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection: "); + connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection:"); if (connection) { if (strncasecmp(connection, "close", sizeof("close")-1) == 0) { http_close = TRUE; @@ -1069,7 +1069,7 @@ try_again: } else { http_close = TRUE; if (use_proxy && !use_ssl) { - connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection: "); + connection = get_http_header_value(ZSTR_VAL(http_headers), "Proxy-Connection:"); if (connection) { if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) { http_close = FALSE; @@ -1078,7 +1078,7 @@ try_again: } } if (http_close == TRUE) { - connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection: "); + connection = get_http_header_value(ZSTR_VAL(http_headers), "Connection:"); if (connection) { if (strncasecmp(connection, "Keep-Alive", sizeof("Keep-Alive")-1) == 0) { http_close = FALSE; @@ -1121,7 +1121,7 @@ try_again: if (http_status >= 300 && http_status < 400) { char *loc; - if ((loc = get_http_header_value(ZSTR_VAL(http_headers), "Location: ")) != NULL) { + if ((loc = get_http_header_value(ZSTR_VAL(http_headers), "Location:")) != NULL) { php_url *new_url = php_url_parse(loc); if (new_url != NULL) { @@ -1170,7 +1170,7 @@ try_again: zval *digest = Z_CLIENT_DIGEST_P(this_ptr); zval *login = Z_CLIENT_LOGIN_P(this_ptr); zval *password = Z_CLIENT_PASSWORD_P(this_ptr); - char *auth = get_http_header_value(ZSTR_VAL(http_headers), "WWW-Authenticate: "); + char *auth = get_http_header_value(ZSTR_VAL(http_headers), "WWW-Authenticate:"); if (auth && strstr(auth, "Digest") == auth && Z_TYPE_P(digest) != IS_ARRAY && Z_TYPE_P(login) == IS_STRING && Z_TYPE_P(password) == IS_STRING) { char *s; @@ -1240,7 +1240,7 @@ try_again: smart_str_free(&soap_headers_z); /* Check and see if the server even sent a xml document */ - content_type = get_http_header_value(ZSTR_VAL(http_headers), "Content-Type: "); + content_type = get_http_header_value(ZSTR_VAL(http_headers), "Content-Type:"); if (content_type) { char *pos = NULL; int cmplen; @@ -1270,7 +1270,7 @@ try_again: } /* Decompress response */ - content_encoding = get_http_header_value(ZSTR_VAL(http_headers), "Content-Encoding: "); + content_encoding = get_http_header_value(ZSTR_VAL(http_headers), "Content-Encoding:"); if (content_encoding) { zval func; zval retval; @@ -1430,18 +1430,18 @@ static zend_string* get_http_body(php_stream *stream, int close, char *headers) int header_close = close, header_chunked = 0, header_length = 0, http_buf_size = 0; if (!close) { - header = get_http_header_value(headers, "Connection: "); + header = get_http_header_value(headers, "Connection:"); if (header) { if(!strncasecmp(header, "close", sizeof("close")-1)) header_close = 1; efree(header); } } - header = get_http_header_value(headers, "Transfer-Encoding: "); + header = get_http_header_value(headers, "Transfer-Encoding:"); if (header) { if(!strncasecmp(header, "chunked", sizeof("chunked")-1)) header_chunked = 1; efree(header); } - header = get_http_header_value(headers, "Content-Length: "); + header = get_http_header_value(headers, "Content-Length:"); if (header) { header_length = atoi(header); efree(header); diff --git a/ext/soap/tests/bugs/bug61525.phpt b/ext/soap/tests/bugs/bug61525.phpt new file mode 100644 index 00000000000..4b5c19e86a4 --- /dev/null +++ b/ext/soap/tests/bugs/bug61525.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #61525 (SOAP functions require at least one space after HTTP header colon) +--EXTENSIONS-- +soap +--SKIPIF-- + +--FILE-- + + + + + 7 + + + +XML; + +$length = strlen($response); +$server_response = "data://text/xml;base64," . base64_encode("HTTP/1.1 200 OK\r\nConnection:close\r\nContent-Length:$length\r\n\r\n$response"); +['pid' => $pid, 'uri' => $uri] = http_server([$server_response]); +$client = new SoapClient(NULL, ['location' => $uri, 'uri' => $uri]); +var_dump($client->Add(3, 4)); +http_server_kill($pid); +?> +--EXPECT-- +int(7)