From f552f9911ba27c3c3d6cf982726a7ef4434434dc 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. --- ext/soap/php_http.c | 24 +++++++++++----------- ext/soap/tests/bugs/bug61525.phpt | 33 +++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 12 deletions(-) create mode 100644 ext/soap/tests/bugs/bug61525.phpt diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 60e8044a82504..bd548b5b303f1 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -980,7 +980,7 @@ int make_http_soap_request(zval *this_ptr, */ 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 @@ int make_http_soap_request(zval *this_ptr, 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 @@ int make_http_soap_request(zval *this_ptr, } } 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 @@ int make_http_soap_request(zval *this_ptr, } 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 @@ int make_http_soap_request(zval *this_ptr, } } 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 @@ int make_http_soap_request(zval *this_ptr, 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 @@ int make_http_soap_request(zval *this_ptr, 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 @@ int make_http_soap_request(zval *this_ptr, 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 @@ int make_http_soap_request(zval *this_ptr, } /* 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 0000000000000..4b5c19e86a4eb --- /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)