diff options
author | Matteo Beccati <mbeccati@php.net> | 2020-08-18 18:27:26 +0200 |
---|---|---|
committer | Matteo Beccati <mbeccati@php.net> | 2020-08-18 18:27:26 +0200 |
commit | 3877172411e7b7f2081af39dfe293e399c98731c (patch) | |
tree | a827d625d06908fbcc2631d4a8241f371f554827 /ext/soap | |
parent | 48d712565ca2c2c6cfd50bb4491df94fd1f05f9d (diff) | |
parent | f7c43b8c72822a4722bd7404c6f65e15b2b912c1 (diff) | |
download | php-git-3877172411e7b7f2081af39dfe293e399c98731c.tar.gz |
Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
Fix #47021: SoapClient stumbles over WSDL delivered with "Transfer-Encoding: chunked"
Diffstat (limited to 'ext/soap')
-rw-r--r-- | ext/soap/php_http.c | 17 | ||||
-rw-r--r-- | ext/soap/tests/bug47021.phpt | 80 |
2 files changed, 95 insertions, 2 deletions
diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index 299fe23a82..0abbefa8a2 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -1367,11 +1367,24 @@ static char *get_http_header_value(char *headers, char *type) /* match */ tmp = pos + typelen; + + /* strip leading whitespace */ + while (*tmp == ' ' || *tmp == '\t') { + tmp++; + } + eol = strchr(tmp, '\n'); if (eol == NULL) { eol = headers + headerslen; - } else if (eol > tmp && *(eol-1) == '\r') { - eol--; + } else if (eol > tmp) { + if (*(eol-1) == '\r') { + eol--; + } + + /* strip trailing whitespace */ + while (eol > tmp && (*(eol-1) == ' ' || *(eol-1) == '\t')) { + eol--; + } } return estrndup(tmp, eol - tmp); } diff --git a/ext/soap/tests/bug47021.phpt b/ext/soap/tests/bug47021.phpt new file mode 100644 index 0000000000..757e74ef15 --- /dev/null +++ b/ext/soap/tests/bug47021.phpt @@ -0,0 +1,80 @@ +--TEST-- +Bug #47021 SoapClient (SoapClient stumbles over WSDL delivered with "Transfer-Encoding: chunked") +--INI-- +soap.wsdl_cache_enabled=0 +--SKIPIF-- +<?php + +require 'skipif.inc'; + +require __DIR__.'/../../standard/tests/http/server.inc'; http_server_skipif('tcp://127.0.0.1:12342'); + +?> +--FILE-- +<?php +require __DIR__.'/../../standard/tests/http/server.inc'; + +function chunk_body($body, $n) +{ + $chunks = str_split($body, $n); + $chunks[] = ''; + + foreach ($chunks as $k => $v) { + $chunks[$k] = sprintf("%08x\r\n%s\r\n", strlen($v), $v); + } + + return join('', $chunks); +} + +$wsdl = file_get_contents(__DIR__.'/server030.wsdl'); + +$soap = <<<EOF +<?xml version="1.0" encoding="UTF-8"?> +<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://testuri.org" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:getItemsResponse><getItemsReturn SOAP-ENC:arrayType="ns1:Item[10]" xsi:type="ns1:ItemArray"><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text0</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text1</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text2</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text3</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text4</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text5</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text6</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text7</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text8</text></item><item xsi:type="ns1:Item"><text xsi:type="xsd:string">text9</text></item></getItemsReturn></ns1:getItemsResponse></SOAP-ENV:Body></SOAP-ENV:Envelope> +EOF; + +$responses = [ + "data://text/plain,HTTP/1.1 200 OK\r\n". + "Content-Type: text/xml;charset=utf-8\r\n". + "Transfer-Encoding: \t chunked\t \r\n". + "Connection: close\r\n". + "\r\n". + chunk_body($wsdl, 64), + "data://text/plain,HTTP/1.1 200 OK\r\n". + "Content-Type: text/xml;charset=utf-8\r\n". + "Transfer-Encoding: \t chunked\t \r\n". + "Connection: close\r\n". + "\r\n". + chunk_body($soap, 156), +]; + + +$pid = http_server('tcp://127.0.0.1:12342', $responses); + +$options = [ + 'trace' => true, + 'location' => 'http://127.0.0.1:12342/', +]; + +class BugSoapClient extends SoapClient +{ + public function __doRequest($request, $location, $action, $version, $one_way = null) + { + $response = parent::__doRequest($request, $location, $action, $version, $one_way); + + var_dump(strlen($response)); + + return $response; + } +} + +$client = new BugSoapClient('http://127.0.0.1:12342/', $options); + +var_dump(count($client->getItems())); + +http_server_kill($pid); + +?> +--EXPECT-- +int(1291) +int(10) |