]> granicus.if.org Git - php/commitdiff
Fix #47021: SoapClient stumbles over WSDL delivered with "Transfer-Encoding: chunked"
authorMatteo Beccati <mbeccati@php.net>
Tue, 18 Aug 2020 16:10:39 +0000 (18:10 +0200)
committerMatteo Beccati <mbeccati@php.net>
Tue, 18 Aug 2020 16:10:39 +0000 (18:10 +0200)
NEWS
ext/soap/php_http.c
ext/soap/tests/bug47021.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 5757c09f517692f33611ced859a315b521e62a1c..4748996c26c8368db5f7fe7ffca31bd84f2c4db6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,10 @@ PHP                                                                        NEWS
   . Fixed bug #64705 (errorInfo property of PDOException is null when
     PDO::__construct() fails). (Ahmed Abdou)
 
+- SOAP:
+  . Fixed bug #47021 (SoapClient stumbles over WSDL delivered with
+    "Transfer-Encoding: chunked"). (Matteo)
+
 - Standard:
   . Fixed bug #79930 (array_merge_recursive() crashes when called with array
     with single reference). (Nikita)
index fb3089ec271aaaaac6d2040220f94f81281d44ac..b054d9ba9ebc60e0ead748bd06779f83a52a4838 100644 (file)
@@ -1375,11 +1375,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 (file)
index 0000000..757e74e
--- /dev/null
@@ -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)