]> granicus.if.org Git - php/commitdiff
Fixed bug #73237
authorKeith Smiley <ksmiley@salesforce.com>
Mon, 27 Jun 2016 18:23:15 +0000 (14:23 -0400)
committerNikita Popov <nikic@php.net>
Wed, 12 Oct 2016 21:12:45 +0000 (23:12 +0200)
If the response includes both fields with simple types (which get
concatenated into an XML string) and a complex type (which is parsed
into an object), then the object will parsed into the same zval as the
simple types and will overwrite the string.

NEWS
ext/soap/php_encoding.c
ext/soap/tests/bugs/bug73237.phpt [new file with mode: 0644]
ext/soap/tests/bugs/bug73237.wsdl [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 2b03b3131c2db20128ea01b1fae14df59b9db227..01d9fe2e30d65744ba556b520cf1cc1545997f79 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,8 @@ PHP                                                                        NEWS
 
 - SOAP:
   . Fixed bug #73037 (SoapServer reports Bad Request when gzipped). (Anatol)
+  . Fixed bug #73237 (Nested object in "any" element overwrites other fields).
+    (Keith Smiley)
 
 - Standard:
   . Fixed bug #73203 (passing additional_parameters causes mail to fail). (cmb)
index 10d59ad57625d54a6d8770177f73419d5f6dcb95..7947b4cea39bf937bc2744384be530b00507ed6b 100644 (file)
@@ -1230,7 +1230,7 @@ static void unset_zval_property(zval* object, char* name)
 
 static void model_to_zval_any(zval *ret, xmlNodePtr node)
 {
-       zval rv, arr, val;
+       zval rv, arr, val, keepVal;
        zval* any = NULL;
        char* name = NULL;
 
@@ -1259,6 +1259,7 @@ static void model_to_zval_any(zval *ret, xmlNodePtr node)
                                        ZVAL_NULL(&val2);
                                        master_to_zval(&val2, get_conversion(XSD_ANYXML), node->next);
                                        if (Z_TYPE(val2) != IS_STRING ||  *Z_STRVAL(val) != '<') {
+                                               Z_TRY_DELREF(val2);
                                                break;
                                        }
                                        concat_function(&val, &val, &val2);
@@ -1277,7 +1278,8 @@ static void model_to_zval_any(zval *ret, xmlNodePtr node)
                                        any = &arr;
                                        name = NULL;
                                } else {
-                                       any = &val;
+                                       ZVAL_COPY_VALUE(&keepVal, &val);
+                                       any = &keepVal;
                                }
                        } else {
                                /* Add array element */
diff --git a/ext/soap/tests/bugs/bug73237.phpt b/ext/soap/tests/bugs/bug73237.phpt
new file mode 100644 (file)
index 0000000..e97345f
--- /dev/null
@@ -0,0 +1,65 @@
+--TEST--
+Bug #73237 "Any" data missing when result includes a struct
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--INI--
+soap.wsdl_cache_enabled=0
+--FILE--
+<?php
+class LocalSoapClient extends SoapClient {
+  function __doRequest($request, $location, $action, $version, $one_way = 0) {
+    return <<<EOF
+<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:test.example.org" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sf="urn:object.test.example.org"><soapenv:Body><queryResponse><result xsi:type="QueryResult"><done>true</done><queryLocator xsi:nil="true"/><records xsi:type="sf:genericObject"><sf:type>CampaignMember</sf:type><sf:Id>00vi0000011VMgeAAG</sf:Id><sf:Id>00vi0000011VMgeAAG</sf:Id><sf:CampaignId>701i0000001lreeAAA</sf:CampaignId><sf:Status>Sent</sf:Status><sf:ContactId xsi:nil="true"/><sf:LeadId>00Qi000001UrbYFEAZ</sf:LeadId><sf:Contact xsi:nil="true"/><sf:Lead xsi:type="sf:genericObject"><sf:type>Lead</sf:type><sf:Id xsi:nil="true"/><sf:Email>angela.lansbury@cbs.com</sf:Email></sf:Lead></records><size>1</size></result></queryResponse></soapenv:Body></soapenv:Envelope>
+EOF;
+  }
+}
+$client = new LocalSoapClient(dirname(__FILE__)."/bug73237.wsdl");
+var_dump($client->query(""));
+?>
+--EXPECT--
+object(stdClass)#2 (1) {
+  ["result"]=>
+  object(stdClass)#3 (4) {
+    ["done"]=>
+    string(4) "true"
+    ["queryLocator"]=>
+    NULL
+    ["records"]=>
+    object(SoapVar)#6 (4) {
+      ["enc_type"]=>
+      int(0)
+      ["enc_value"]=>
+      object(stdClass)#4 (3) {
+        ["type"]=>
+        string(14) "CampaignMember"
+        ["Id"]=>
+        array(2) {
+          [0]=>
+          string(18) "00vi0000011VMgeAAG"
+          [1]=>
+          string(18) "00vi0000011VMgeAAG"
+        }
+        ["any"]=>
+        array(2) {
+          [0]=>
+          string(175) "<sf:CampaignId>701i0000001lreeAAA</sf:CampaignId><sf:Status>Sent</sf:Status><sf:ContactId xsi:nil="true"/><sf:LeadId>00Qi000001UrbYFEAZ</sf:LeadId><sf:Contact xsi:nil="true"/>"
+          ["Lead"]=>
+          object(stdClass)#5 (3) {
+            ["type"]=>
+            string(4) "Lead"
+            ["Id"]=>
+            NULL
+            ["any"]=>
+            string(44) "<sf:Email>angela.lansbury@cbs.com</sf:Email>"
+          }
+        }
+      }
+      ["enc_stype"]=>
+      string(13) "genericObject"
+      ["enc_ns"]=>
+      string(27) "urn:object.test.example.org"
+    }
+    ["size"]=>
+    string(1) "1"
+  }
+}
diff --git a/ext/soap/tests/bugs/bug73237.wsdl b/ext/soap/tests/bugs/bug73237.wsdl
new file mode 100644 (file)
index 0000000..230338c
--- /dev/null
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions targetNamespace="urn:test.example.org"
+             xmlns="http://schemas.xmlsoap.org/wsdl/"
+             xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
+             xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+             xmlns:tns="urn:test.example.org"
+             xmlns:ens="urn:object.test.example.org">
+    <types>
+        <schema elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:object.test.example.org">
+            <import namespace="urn:test.example.org"/>
+            <complexType name="genericObject">
+                <sequence>
+                    <element name="type"               type="xsd:string"/>
+                    <element name="fieldsToNull"       type="xsd:string" nillable="true" minOccurs="0" maxOccurs="unbounded"/>
+                    <element name="Id"                 type="tns:ID" nillable="true" />
+                    <any namespace="##targetNamespace" minOccurs="0" maxOccurs="unbounded" processContents="lax"/>
+                </sequence>
+            </complexType>
+        </schema>
+               <schema elementFormDefault="qualified" xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:test.example.org">
+                       <import namespace="urn:object.test.example.org"/>
+            <simpleType name="ID">
+                <restriction base="xsd:string">
+                    <length value="18"/>
+                    <pattern value='[a-zA-Z0-9]{18}'/>
+                </restriction>
+            </simpleType>
+            <element name="query">
+                <complexType>
+                    <sequence>
+                        <element name="queryString" type="xsd:string"/>
+                    </sequence>
+                </complexType>
+            </element>
+            <element name="queryResponse">
+                <complexType>
+                    <sequence>
+                        <element name="result" type="tns:QueryResult"/>
+                    </sequence>
+                </complexType>
+            </element>
+        </schema>
+    </types>
+
+    <message name="queryRequest">
+        <part element="tns:query" name="parameters"/>
+    </message>
+    <message name="queryResponse">
+        <part element="tns:queryResponse" name="parameters"/>
+    </message>
+
+    <portType name="Soap">
+        <operation name="query">
+            <documentation>Create a Query Cursor</documentation>
+            <input  message="tns:queryRequest"/>
+            <output message="tns:queryResponse"/>
+        </operation>
+    </portType>
+
+    <binding name="SoapBinding" type="tns:Soap">
+        <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+        <operation name="query">
+            <soap:operation soapAction=""/>
+            <input>
+                <soap:body parts="parameters" use="literal"/>
+            </input>
+            <output>
+                <soap:body use="literal"/>
+            </output>
+        </operation>
+    </binding>
+
+    <service name="TestService">
+        <port binding="tns:SoapBinding" name="Soap">
+            <soap:address location="https://localhost/services/Soap/u/31.0"/>
+        </port>
+    </service>
+</definitions>