Fixed bug #37013 (server hangs when returning circular object references)

This commit is contained in:
Dmitry Stogov 2007-04-02 13:43:08 +00:00
parent 2429299507
commit 36c6ad915b
17 changed files with 440 additions and 31 deletions

2
NEWS
View File

@ -146,6 +146,8 @@ PHP NEWS
statements in mysqli) (Stas)
- Fixed bug #37386 (autocreating element doesn't assign value to first node).
(Rob)
- Fixed bug #37013 (server hangs when returning circular object references).
(Dmitry)
- Fixed unallocated memory access/double free in in array_user_key_compare()
(MOPB-24 by Stefan Esser) (Stas)
- Fixed wrong length calculation in unserialize S type

View File

@ -270,6 +270,85 @@ static encodePtr find_encoder_by_type_name(sdlPtr sdl, const char *type)
return NULL;
}
static zend_bool soap_check_zval_ref(zval *data, xmlNodePtr node TSRMLS_DC) {
xmlNodePtr *node_ptr;
if (SOAP_GLOBAL(ref_map)) {
if (Z_TYPE_P(data) == IS_OBJECT) {
data = (zval*)zend_objects_get_address(data TSRMLS_CC);
}
if (zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)data, (void**)&node_ptr) == SUCCESS) {
xmlAttrPtr attr = (*node_ptr)->properties;
char *id;
smart_str prefix = {0};
if (*node_ptr == node) {
return 0;
}
xmlNodeSetName(node, (*node_ptr)->name);
xmlSetNs(node, (*node_ptr)->ns);
if (SOAP_GLOBAL(soap_version) == SOAP_1_1) {
while (1) {
attr = get_attribute(attr, "id");
if (attr == NULL || attr->ns == NULL) {
break;
}
attr = attr->next;
}
if (attr) {
id = (char*)attr->children->content;
} else {
SOAP_GLOBAL(cur_uniq_ref)++;
smart_str_appendl(&prefix, "#ref", 4);
smart_str_append_long(&prefix, SOAP_GLOBAL(cur_uniq_ref));
smart_str_0(&prefix);
id = prefix.c;
xmlSetProp((*node_ptr), BAD_CAST("id"), BAD_CAST(id+1));
}
xmlSetProp(node, BAD_CAST("href"), BAD_CAST(id));
} else {
attr = get_attribute_ex(attr, "id", SOAP_1_2_ENC_NAMESPACE);
if (attr) {
id = (char*)attr->children->content;
} else {
SOAP_GLOBAL(cur_uniq_ref)++;
smart_str_appendl(&prefix, "#ref", 4);
smart_str_append_long(&prefix, SOAP_GLOBAL(cur_uniq_ref));
smart_str_0(&prefix);
id = prefix.c;
set_ns_prop((*node_ptr), SOAP_1_2_ENC_NAMESPACE, "id", id+1);
}
set_ns_prop(node, SOAP_1_2_ENC_NAMESPACE, "ref", id);
}
smart_str_free(&prefix);
return 1;
} else {
zend_hash_index_update(SOAP_GLOBAL(ref_map), (ulong)data, (void**)&node, sizeof(xmlNodePtr), NULL);
}
}
return 0;
}
static zend_bool soap_check_xml_ref(zval **data, xmlNodePtr node TSRMLS_DC)
{
zval **data_ptr;
if (SOAP_GLOBAL(ref_map)) {
if (zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)node, (void**)&data_ptr) == SUCCESS) {
if (*data != *data_ptr) {
zval_ptr_dtor(data);
*data = *data_ptr;
(*data)->is_ref = 1;
(*data)->refcount++;
return 1;
}
} else {
zend_hash_index_update(SOAP_GLOBAL(ref_map), (ulong)node, (void**)data, sizeof(zval*), NULL);
}
}
return 0;
}
xmlNodePtr master_to_xml(encodePtr encode, zval *data, int style, xmlNodePtr parent)
{
xmlNodePtr node = NULL;
@ -1303,14 +1382,20 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e
if (enc) {
zval *base;
MAKE_STD_ZVAL(ret);
ALLOC_INIT_ZVAL(ret);
if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
return ret;
}
object_init_ex(ret, ce);
base = master_to_zval_int(enc, data);
set_zval_property(ret, "_", base TSRMLS_CC);
} else {
MAKE_STD_ZVAL(ret);
ALLOC_INIT_ZVAL(ret);
FIND_XML_NULL(data, ret);
if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
return ret;
}
object_init_ex(ret, ce);
}
} else if (sdlType->kind == XSD_TYPEKIND_EXTENSION &&
@ -1335,6 +1420,9 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e
ret = master_to_zval_int(sdlType->encode, data);
}
FIND_XML_NULL(data, ret);
if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
return ret;
}
if (get_zval_property(ret, "any" TSRMLS_CC) != NULL) {
unset_zval_property(ret, "any" TSRMLS_CC);
redo_any = 1;
@ -1346,15 +1434,21 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e
} else {
zval *base;
MAKE_STD_ZVAL(ret);
ALLOC_INIT_ZVAL(ret);
if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
return ret;
}
object_init_ex(ret, ce);
base = master_to_zval_int(sdlType->encode, data);
set_zval_property(ret, "_", base TSRMLS_CC);
}
} else {
MAKE_STD_ZVAL(ret);
ALLOC_INIT_ZVAL(ret);
FIND_XML_NULL(data, ret);
if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
return ret;
}
object_init_ex(ret, ce);
}
if (sdlType->model) {
@ -1400,10 +1494,13 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e
}
} else {
MAKE_STD_ZVAL(ret);
ALLOC_INIT_ZVAL(ret);
FIND_XML_NULL(data, ret);
object_init_ex(ret, ce);
if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
return ret;
}
object_init_ex(ret, ce);
trav = data->children;
while (trav != NULL) {
@ -1719,10 +1816,13 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo
xmlAddChild(parent, xmlParam);
}
if (soap_check_zval_ref(data, xmlParam TSRMLS_CC)) {
return xmlParam;
}
if (prop != NULL) {
sdlTypePtr array_el;
sdlTypePtr array_el;
if (Z_TYPE_P(data) == IS_ARRAY &&
if (Z_TYPE_P(data) == IS_ARRAY &&
!is_map(data) &&
sdlType->attributes == NULL &&
sdlType->model != NULL &&
@ -1796,6 +1896,9 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo
xmlParam = xmlNewNode(NULL, BAD_CAST("BOGUS"));
xmlAddChild(parent, xmlParam);
if (soap_check_zval_ref(data, xmlParam TSRMLS_CC)) {
return xmlParam;
}
if (prop != NULL) {
i = zend_hash_num_elements(prop);
zend_hash_internal_pointer_reset(prop);
@ -3214,6 +3317,25 @@ void encode_reset_ns()
{
TSRMLS_FETCH();
SOAP_GLOBAL(cur_uniq_ns) = 0;
SOAP_GLOBAL(cur_uniq_ref) = 0;
if (SOAP_GLOBAL(ref_map)) {
zend_hash_destroy(SOAP_GLOBAL(ref_map));
} else {
SOAP_GLOBAL(ref_map) = emalloc(sizeof(HashTable));
}
zend_hash_init(SOAP_GLOBAL(ref_map), 0, NULL, NULL, 0);
}
void encode_finish()
{
TSRMLS_FETCH();
SOAP_GLOBAL(cur_uniq_ns) = 0;
SOAP_GLOBAL(cur_uniq_ref) = 0;
if (SOAP_GLOBAL(ref_map)) {
zend_hash_destroy(SOAP_GLOBAL(ref_map));
efree(SOAP_GLOBAL(ref_map));
SOAP_GLOBAL(ref_map) = NULL;
}
}
encodePtr get_conversion(int encode)

View File

@ -201,6 +201,7 @@ void whiteSpace_collapse(xmlChar* str);
xmlNodePtr sdl_guess_convert_xml(encodeTypePtr enc, zval* data, int style, xmlNodePtr parent);
zval *sdl_guess_convert_zval(encodeTypePtr enc, xmlNodePtr data);
void encode_finish();
void encode_reset_ns();
xmlNsPtr encode_add_ns(xmlNodePtr node, const char* ns);

View File

@ -168,6 +168,8 @@ ZEND_BEGIN_MODULE_GLOBALS(soap)
HashTable *class_map;
int features;
HashTable wsdl_cache;
int cur_uniq_ref;
HashTable *ref_map;
ZEND_END_MODULE_GLOBALS(soap)
#ifdef PHP_WIN32

View File

@ -479,6 +479,7 @@ static void php_soap_init_globals(zend_soap_globals *soap_globals TSRMLS_DC)
soap_globals->sdl = NULL;
soap_globals->soap_version = SOAP_1_1;
soap_globals->mem_cache = NULL;
soap_globals->ref_map = NULL;
}
PHP_MSHUTDOWN_FUNCTION(soap)
@ -2583,7 +2584,9 @@ static void do_soap_call(zval* this_ptr,
xmlFreeDoc(request);
if (ret && Z_TYPE(response) == IS_STRING) {
encode_reset_ns();
ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), fn, NULL, return_value, output_headers TSRMLS_CC);
encode_finish();
}
zval_dtor(&response);
@ -2626,7 +2629,9 @@ static void do_soap_call(zval* this_ptr,
xmlFreeDoc(request);
if (ret && Z_TYPE(response) == IS_STRING) {
encode_reset_ns();
ret = parse_packet_soap(this_ptr, Z_STRVAL(response), Z_STRLEN(response), NULL, function, return_value, output_headers TSRMLS_CC);
encode_finish();
}
zval_dtor(&response);
@ -3282,6 +3287,8 @@ static sdlFunctionPtr deserialize_function_call(sdlPtr sdl, xmlDocPtr request, c
xmlAttrPtr attr;
sdlFunctionPtr function;
encode_reset_ns();
/* Get <Envelope> element */
env = NULL;
trav = request->children;
@ -3530,6 +3537,9 @@ ignore_header:
func = func->children;
}
deserialize_parameters(func, function, num_params, parameters);
encode_finish();
return function;
}
@ -3982,6 +3992,8 @@ static xmlDocPtr serialize_response_call(sdlFunctionPtr function, char *function
}
}
encode_finish();
if (function && function->responseName == NULL &&
body->children == NULL && head == NULL) {
xmlFreeDoc(doc);
@ -4196,6 +4208,8 @@ static xmlDocPtr serialize_function_call(zval *this_ptr, sdlFunctionPtr function
}
}
encode_finish();
return doc;
}

View File

@ -0,0 +1,50 @@
--TEST--
Bug #36999 (xsd:long values clamped to LONG_MAX instead of using double)
--SKIPIF--
<?php
if (!extension_loaded('soap')) die('skip soap extension not available');
?>
--INI--
soap.wsdl_cache_enabled=0
--FILE--
<?php
function echoLong($num) {
return $num;
}
class LocalSoapClient extends SoapClient {
function __construct($wsdl) {
parent::__construct($wsdl);
$this->server = new SoapServer($wsdl);
$this->server->addFunction('echoLong');
}
function __doRequest($request, $location, $action, $version) {
ob_start();
$this->server->handle($request);
$response = ob_get_contents();
ob_end_clean();
return $response;
}
}
$soap = new LocalSoapClient(dirname(__FILE__)."/bug36999.wsdl");
function test($num) {
global $soap;
try {
printf("%s %0.0f\n", gettype($num), $num);
$ret = $soap->echoLong($num);
printf("%s %0.0f\n", gettype($ret), $ret);
} catch (SoapFault $ex) {
var_dump($ex);
}
}
test(3706790240);
?>
--EXPECTF--
%s 3706790240
%s 3706790240

View File

@ -0,0 +1,48 @@
<?xml version="1.0" ?>
<definitions
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:si="http://soapinterop.org/xsd"
xmlns:tns="http://linuxsrv.home/~dmitry/soap/test.wsdl"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://linuxsrv.home/~dmitry/soap/test.wsdl">
<message name="echoLongRequest">
<part name="x" type="xsd:long" />
</message>
<message name="echoLongResponse">
<part name="x" type="xsd:long" />
</message>
<portType name="TestServicePortType">
<operation name="echoLong">
<input message="tns:echoLongRequest" />
<output message="tns:echoLongResponse" />
</operation>
</portType>
<binding name="TestServiceBinding" type="tns:TestServicePortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="echoLong">
<soap:operation style="rpc" />
<input>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
</binding>
<service name="TestService">
<port name="TestServicePort" binding="tns:TestServiceBinding">
<soap:address location="test://" />
</port>
</service>
</definitions>

View File

@ -0,0 +1,58 @@
--TEST--
Bug #37013 (server hangs when returning circular object references)
--SKIPIF--
<?php
if (!extension_loaded('soap')) die('skip soap extension not available');
?>
--INI--
soap.wsdl_cache_enabled=0
--FILE--
<?php
$request = <<<REQUEST
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns2:getThingWithParent
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns2="urn:test.soapserver#"/>
</soapenv:Body>
</soapenv:Envelope>
REQUEST;
class ThingWithParent
{
var $parent;
var $id;
var $children;
function __construct( $id, $parent ) {
$this->id = $id;
$this->parent = $parent;
}
}
class MultiRefTest {
public function getThingWithParent() {
$p = new ThingWithParent( 1, null );
$p2 = new ThingWithParent( 2, $p );
$p3 = new ThingWithParent( 3, $p );
$p->children = array( $p2, $p3 );
return $p2;
}
}
$server = new SoapServer(dirname(__FILE__)."/bug37013.wsdl");
$server->setClass( "MultiRefTest");
$server->handle( $request );
?>
--EXPECT--
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="urn:test.soapserver#" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:getThingWithParentResponse><result id="ref1" xsi:type="SOAP-ENC:Struct"><parent id="ref2" xsi:type="SOAP-ENC:Struct"><parent xsi:nil="true"/><id xsi:type="xsd:int">1</id><children SOAP-ENC:arrayType="SOAP-ENC:Struct[2]" xsi:type="SOAP-ENC:Array"><item href="#ref1"/><item xsi:type="SOAP-ENC:Struct"><parent href="#ref2"/><id xsi:type="xsd:int">3</id><children xsi:nil="true"/></item></children></parent><id xsi:type="xsd:int">2</id><children xsi:nil="true"/></result></ns1:getThingWithParentResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>

View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<definitions name="shoppingcart"
xmlns="http://schemas.xmlsoap.org/wsdl/"
xmlns:tns="urn:test.soapserver#"
targetNamespace="urn:test.soapserver#"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:types="urn:test.soapserver.types#">
<!-- all datatypes will be imported to namespace types: -->
<types>
<xs:schema targetNamespace="urn:test.soapserver.types#">
<xs:complexType name="ThingWithParent">
<xs:all>
<xs:element name="id" type="xs:string"/>
<xs:element name="parent" type="types:ThingWithParent"/>
<xs:element name="children" type="types:ArrayOfThingWithParent"/>
</xs:all>
</xs:complexType>
<xs:complexType name="ArrayOfThingWithParent">
<xs:complexContent>
<xs:restriction base="soapenc:Array">
<xs:attribute ref="soapenc:arrayType"
wsdl:arrayType="tns:ThingWithParent[]"/>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
</xs:schema>
</types>
<message name="getThingWithParent-request"/>
<message name="getThingWithParent-response">
<part name="result" element="types:ThingWithParent"/>
</message>
<portType name="soapserver-porttype">
<operation name="getThingWithParent">
<input name="getThingWithParent-request" message="tns:getThingWithParent-request"/>
<output name="getThingWithParent-response" message="tns:getThingWithParent-response"/>
</operation>
</portType>
<binding name="soapserver-binding" type="tns:soapserver-porttype">
<soap:binding style="rpc"
transport="http://schemas.xmlsoap.org/soap/http"/>
<operation name="getThingWithParent">
<soap:operation soapAction="urn:test.soapserver.SoapServer#getThingWithParent"/>
<input>
<soap:body use="encoded"
namespace="urn:test.soapserver#"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</input>
<output>
<soap:body use="encoded"
namespace="urn:test.soapserver#"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
</output>
</operation>
</binding>
<service name="soapserver">
<!-- @binding doesn't like to be tns: -->
<port name="soapserver-port" binding="tns:soapserver-binding">
<soap:address location="xxxxxxxxxxxx"/>
</port>
</service>
</definitions>

View File

@ -12,9 +12,10 @@ class SOAPStruct {
}
}
$struct = new SOAPStruct('arg',34,325.325);
$struct1 = new SOAPStruct('arg',34,325.325);
$struct2 = new SOAPStruct('arg',34,325.325);
$client = new SoapClient(NULL,array("location"=>"test://","uri"=>"http://soapinterop.org/","trace"=>1,"exceptions"=>0));
$client->__soapCall("echoStructArray", array(array($struct,$struct)), array("soapaction"=>"http://soapinterop.org/","uri"=>"http://soapinterop.org/"));
$client->__soapCall("echoStructArray", array(array($struct1,$struct2)), array("soapaction"=>"http://soapinterop.org/","uri"=>"http://soapinterop.org/"));
echo $client->__getlastrequest();
$HTTP_RAW_POST_DATA = $client->__getlastrequest();
include("round2_base.inc");

View File

@ -12,17 +12,21 @@ class SOAPStruct {
}
}
$struct = new SoapVar(array(
$struct1 = new SoapVar(array(
new SoapVar('arg', XSD_STRING, null, null, 'varString'),
new SoapVar('34', XSD_INT, null, null, 'varInt'),
new SoapVar('325.325', XSD_FLOAT, null, null, 'varFloat')
),SOAP_ENC_OBJECT,"SOAPStruct","http://soapinterop.org/xsd");
$struct2 = new SoapVar(array(
new SoapVar('arg', XSD_STRING, null, null, 'varString'),
new SoapVar('34', XSD_INT, null, null, 'varInt'),
new SoapVar('325.325', XSD_FLOAT, null, null, 'varFloat')
),SOAP_ENC_OBJECT,"SOAPStruct","http://soapinterop.org/xsd");
$param = new SoapParam(new SoapVar(array(
$struct,
$struct
$struct1,
$struct2
),SOAP_ENC_ARRAY,"ArrayOfSOAPStruct","http://soapinterop.org/xsd"), "inputStructArray");
$struct = new SOAPStruct('arg',34,325.325);
$client = new SoapClient(NULL,array("location"=>"test://","uri"=>"http://soapinterop.org/","trace"=>1,"exceptions"=>0));
$client->__soapCall("echoStructArray", array($param), array("soapaction"=>"http://soapinterop.org/","uri"=>"http://soapinterop.org/"));
echo $client->__getlastrequest();

View File

@ -12,9 +12,10 @@ class SOAPStruct {
}
}
$struct = new SOAPStruct('arg',34,325.325);
$struct1 = new SOAPStruct('arg',34,325.325);
$struct2 = new SOAPStruct('arg',34,325.325);
$client = new SoapClient(dirname(__FILE__)."/round2_base.wsdl",array("trace"=>1,"exceptions"=>0));
$client->echoStructArray(array($struct,$struct));
$client->echoStructArray(array($struct1,$struct2));
echo $client->__getlastrequest();
$HTTP_RAW_POST_DATA = $client->__getlastrequest();
include("round2_base.inc");

View File

@ -11,9 +11,10 @@ class SOAPStruct {
$this->varFloat = $f;
}
}
$struct = new SOAPStruct('arg',34,325.325);
$struct1 = new SOAPStruct('arg',34,325.325);
$struct2 = new SOAPStruct('arg',34,325.325);
$client = new SoapClient(dirname(__FILE__)."/round3_groupD_import3.wsdl",array("trace"=>1,"exceptions"=>0));
$client->echoStructArray(array($struct,$struct));
$client->echoStructArray(array($struct1,$struct2));
echo $client->__getlastrequest();
$HTTP_RAW_POST_DATA = $client->__getlastrequest();
include("round3_groupD_import3.inc");

View File

@ -1,7 +1,7 @@
--TEST--
SOAP Interop Round3 GroupE List 005 (php/wsdl): echoLinkedList (cyclic)
--SKIPIF--
<?php require_once('skipif.inc'); die('skip cyclic stuctures are not supported yet'); ?>
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
class SOAPList {
@ -22,9 +22,9 @@ echo "ok\n";
?>
--EXPECT--
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://soapinterop.org/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedList><param0 xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child xsi:nil="1" xsi:type="ns2:List"/></child></child></param0></ns1:echoLinkedList></SOAP-ENV:Body></SOAP-ENV:Envelope>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://soapinterop.org/xsd" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedList><param0 id="ref1" xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child href="#ref1"/></child></child></param0></ns1:echoLinkedList></SOAP-ENV:Body></SOAP-ENV:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://soapinterop.org/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedListResponse><return xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child xsi:nil="1" xsi:type="ns2:List"/></child></child></return></ns1:echoLinkedListResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://soapinterop.org/xsd" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedListResponse><return id="ref1" xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child href="#ref1"/></child></child></return></ns1:echoLinkedListResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
object(stdClass)#7 (3) {
["varInt"]=>
int(1)
@ -43,7 +43,28 @@ object(stdClass)#7 (3) {
["varString"]=>
string(4) "arg3"
["child"]=>
NULL
object(stdClass)#7 (3) {
["varInt"]=>
int(1)
["varString"]=>
string(4) "arg1"
["child"]=>
object(stdClass)#8 (3) {
["varInt"]=>
int(2)
["varString"]=>
string(4) "arg2"
["child"]=>
object(stdClass)#9 (3) {
["varInt"]=>
int(3)
["varString"]=>
string(4) "arg3"
["child"]=>
*RECURSION*
}
}
}
}
}
}

View File

@ -1,7 +1,7 @@
--TEST--
SOAP Interop Round3 GroupE List 006 (php/wsdl): echoLinkedList (cyclic)
--SKIPIF--
<?php require_once('skipif.inc'); die("skip cyclic stuctures are not supported yet"); ?>
<?php require_once('skipif.inc'); ?>
--FILE--
<?php
class SOAPList {
@ -22,16 +22,16 @@ echo "ok\n";
?>
--EXPECT--
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://soapinterop.org/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedList><param0 xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child xsi:nil="1" xsi:type="ns2:List"/></child></child></param0></ns1:echoLinkedList></SOAP-ENV:Body></SOAP-ENV:Envelope>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://soapinterop.org/xsd" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedList><param0 xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child id="ref1" xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child href="#ref1"/></child></child></param0></ns1:echoLinkedList></SOAP-ENV:Body></SOAP-ENV:Envelope>
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns2="http://soapinterop.org/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedListResponse><return xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child xsi:nil="1" xsi:type="ns2:List"/></child></child></return></ns1:echoLinkedListResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://soapinterop.org/WSDLInteropTestRpcEnc" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://soapinterop.org/xsd" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:echoLinkedListResponse><return xsi:type="ns2:List"><varInt xsi:type="xsd:int">1</varInt><varString xsi:type="xsd:string">arg1</varString><child id="ref1" xsi:type="ns2:List"><varInt xsi:type="xsd:int">2</varInt><varString xsi:type="xsd:string">arg2</varString><child xsi:type="ns2:List"><varInt xsi:type="xsd:int">3</varInt><varString xsi:type="xsd:string">arg3</varString><child href="#ref1"/></child></child></return></ns1:echoLinkedListResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
object(stdClass)#7 (3) {
["varInt"]=>
int(1)
["varString"]=>
string(4) "arg1"
["child"]=>
object(stdClass)#8 (3) {
&object(stdClass)#8 (3) {
["varInt"]=>
int(2)
["varString"]=>
@ -43,7 +43,21 @@ object(stdClass)#7 (3) {
["varString"]=>
string(4) "arg3"
["child"]=>
NULL
object(stdClass)#8 (3) {
["varInt"]=>
int(2)
["varString"]=>
string(4) "arg2"
["child"]=>
object(stdClass)#9 (3) {
["varInt"]=>
int(3)
["varString"]=>
string(4) "arg3"
["child"]=>
*RECURSION*
}
}
}
}
}

View File

@ -11,9 +11,11 @@ class SOAPComplexType {
$this->varFloat = $f;
}
}
$struct = new SOAPComplexType('arg',34,325.325);
$struct1 = new SOAPComplexType('arg',34,325.325);
$struct2 = new SOAPComplexType('arg',34,325.325);
$struct3 = new SOAPComplexType('arg',34,325.325);
$client = new SoapClient(dirname(__FILE__)."/round4_groupI_xsd.wsdl",array("trace"=>1,"exceptions"=>0));
$client->echoComplexTypeMultiOccurs(array("inputComplexTypeMultiOccurs"=>array($struct,$struct,$struct)));
$client->echoComplexTypeMultiOccurs(array("inputComplexTypeMultiOccurs"=>array($struct1,$struct2,$struct3)));
echo $client->__getlastrequest();
$HTTP_RAW_POST_DATA = $client->__getlastrequest();
include("round4_groupI_xsd.inc");

View File

@ -11,9 +11,10 @@ class SOAPComplexType {
$this->varFloat = $f;
}
}
$struct = new SOAPComplexType('arg',34,325.325);
$struct1 = new SOAPComplexType('arg',34,325.325);
$struct2 = new SOAPComplexType('arg',34,325.325);
$client = new SoapClient(dirname(__FILE__)."/round4_groupI_xsd.wsdl",array("trace"=>1,"exceptions"=>0));
$client->echoComplexTypeMultiOccurs(array("inputComplexTypeMultiOccurs"=>array($struct,null,$struct)));
$client->echoComplexTypeMultiOccurs(array("inputComplexTypeMultiOccurs"=>array($struct1,null,$struct2)));
echo $client->__getlastrequest();
$HTTP_RAW_POST_DATA = $client->__getlastrequest();
include("round4_groupI_xsd.inc");