summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Stogov <dmitry@php.net>2011-08-10 13:44:48 +0000
committerDmitry Stogov <dmitry@php.net>2011-08-10 13:44:48 +0000
commit6ddfa33aade1e05e3e26aaf1592d3756888e838a (patch)
treeccfebecf12d27298f1a6583f6a15a75b25048a21
parent8f54a74d605f716ee9b71b706eb3470dc7973bc8 (diff)
downloadphp-git-6ddfa33aade1e05e3e26aaf1592d3756888e838a.tar.gz
Fixed bug #55323 (SoapClient segmentation fault when XSD_TYPEKIND_EXTENSION contains itself)
-rw-r--r--NEWS7
-rw-r--r--ext/soap/php_encoding.c39
-rw-r--r--ext/soap/tests/bugs/bug55323.phpt45
-rw-r--r--ext/soap/tests/bugs/bug55323.wsdl50
4 files changed, 139 insertions, 2 deletions
diff --git a/NEWS b/NEWS
index 2e358f4d83..b1042df252 100644
--- a/NEWS
+++ b/NEWS
@@ -10,7 +10,12 @@ PHP NEWS
- MySQLi extension:
. Fixed bug #55238 (SSL options set by mysqli_ssl_set ignored for MySQLi
persistent connections). (Andrey)
-
+
+- SOAP
+ . Fixed bug #55323 (SoapClient segmentation fault when XSD_TYPEKIND_EXTENSION
+ contains itself). (Dmitry)
+
+
28 Jul 2011, PHP 5.3.7 RC4
- Improved core functions:
. Updated crypt_blowfish to 1.2. ((CVE-2011-2483) (Solar Designer)
diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c
index 7ee031056f..8513498f4c 100644
--- a/ext/soap/php_encoding.c
+++ b/ext/soap/php_encoding.c
@@ -114,6 +114,26 @@ static void set_ns_and_type(xmlNodePtr node, encodeTypePtr type);
} \
}
+#define CHECK_XML_NULL(xml) \
+ { \
+ xmlAttrPtr null; \
+ if (!xml) { \
+ zval *ret; \
+ ALLOC_INIT_ZVAL(ret); \
+ ZVAL_NULL(ret); \
+ return ret; \
+ } \
+ if (xml->properties) { \
+ null = get_attribute(xml->properties, "nil"); \
+ if (null) { \
+ zval *ret; \
+ ALLOC_INIT_ZVAL(ret); \
+ ZVAL_NULL(ret); \
+ return ret; \
+ } \
+ } \
+ }
+
#define FIND_ZVAL_NULL(zval, xml, style) \
{ \
if (!zval || Z_TYPE_P(zval) == IS_NULL) { \
@@ -338,6 +358,19 @@ static zend_bool soap_check_zval_ref(zval *data, xmlNodePtr node TSRMLS_DC) {
return 0;
}
+static zval* soap_find_xml_ref(xmlNodePtr node TSRMLS_DC)
+{
+ zval **data_ptr;
+
+ if (SOAP_GLOBAL(ref_map) &&
+ zend_hash_index_find(SOAP_GLOBAL(ref_map), (ulong)node, (void**)&data_ptr) == SUCCESS) {
+ Z_SET_ISREF_PP(data_ptr);
+ Z_ADDREF_PP(data_ptr);
+ return *data_ptr;
+ }
+ return NULL;
+}
+
static zend_bool soap_check_xml_ref(zval **data, xmlNodePtr node TSRMLS_DC)
{
zval **data_ptr;
@@ -1513,6 +1546,11 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e
sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_LIST &&
sdlType->encode->details.sdl_type->kind != XSD_TYPEKIND_UNION) {
+ CHECK_XML_NULL(data);
+ if ((ret = soap_find_xml_ref(data TSRMLS_CC)) != NULL) {
+ return ret;
+ }
+
if (ce != ZEND_STANDARD_CLASS_DEF_PTR &&
sdlType->encode->to_zval == sdl_guess_convert_zval &&
sdlType->encode->details.sdl_type != NULL &&
@@ -1526,7 +1564,6 @@ static zval *to_zval_object_ex(encodeTypePtr type, xmlNodePtr data, zend_class_e
} else {
ret = master_to_zval_int(sdlType->encode, data);
}
- FIND_XML_NULL(data, ret);
if (soap_check_xml_ref(&ret, data TSRMLS_CC)) {
return ret;
}
diff --git a/ext/soap/tests/bugs/bug55323.phpt b/ext/soap/tests/bugs/bug55323.phpt
new file mode 100644
index 0000000000..7855dd845a
--- /dev/null
+++ b/ext/soap/tests/bugs/bug55323.phpt
@@ -0,0 +1,45 @@
+--TEST--
+Bug #55323 (SoapClient segmentation fault when XSD_TYPEKIND_EXTENSION contains itself)
+--SKIPIF--
+<?php require_once('skipif.inc'); ?>
+--FILE--
+<?php
+ini_set("soap.wsdl_cache_enabled",0);
+$timestamp = "2011-07-30T03:25:00-05:00";
+$wsdl = dirname(__FILE__)."/bug55323.wsdl";
+
+class TestSoapClient extends SoapClient {
+
+ function __construct($wsdl, $options) {
+ parent::__construct($wsdl, $options);
+ }
+
+ function __doRequest($request, $location, $action, $version, $one_way = 0) {
+ return <<<EOF
+<SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://test.com/soap/v3/" 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:Body>
+ <ns1:getObjectResponse>
+ <getObjectReturn xsi:type="ns1:Customer" id="ref1">
+ <accountId xsi:type="xsd:int">1234</accountId>
+ <parent href="#ref1"/>
+ </getObjectReturn>
+ </ns1:getObjectResponse>
+ </SOAP-ENV:Body>
+</SOAP-ENV:Envelope>
+EOF;
+ }
+
+}
+
+$soapClient = new TestSoapClient($wsdl,
+ array('trace' => 1, 'exceptions' => 0));
+$result = $soapClient->getObject();
+var_dump($result);
+?>
+--EXPECTF--
+object(stdClass)#%d (2) {
+ ["accountId"]=>
+ int(1234)
+ ["parent"]=>
+ *RECURSION*
+}
diff --git a/ext/soap/tests/bugs/bug55323.wsdl b/ext/soap/tests/bugs/bug55323.wsdl
new file mode 100644
index 0000000000..c260d34f4e
--- /dev/null
+++ b/ext/soap/tests/bugs/bug55323.wsdl
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://test.com/soap/v3/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap-enc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" name="slApi" targetNamespace="http://test.com/soap/v3/">
+ <types>
+ <xsd:schema xmlns="http://www.w3.org/2001/XMLSchema"
+ targetNamespace="http://test.com/soap/v3/"
+ xmlns:tns="http://test.com/soap/v3/"
+ xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
+ elementFormDefault="qualified">
+ <complexType name="Customer">
+ <complexContent>
+ <extension base="tns:Interface">
+ <sequence>
+ <element minOccurs="0" maxOccurs="1" nillable="true" name="accountId" type="int"/>
+ <element minOccurs="0" maxOccurs="1" name="parent" type="tns:Customer"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+ <complexType name="Interface" abstract="true"/>
+ </xsd:schema>
+ </types>
+ <message name="getObject"/>
+ <message name="getObjectResponse">
+ <part name="getObjectReturn" type="tns:Customer"/>
+ </message>
+ <portType name="CustomerPortType">
+ <operation name="getObject">
+ <input message="tns:getObject"/>
+ <output message="tns:getObjectResponse"/>
+ </operation>
+ </portType>
+ <binding name="CustomerBinding" type="tns:CustomerPortType">
+ <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
+ <operation name="getObject">
+ <soap:operation soapAction="http://test.com/soap/v3/CustomerAction"/>
+ <input>
+ <soap:body namespace="http://test.com/soap/v3/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </input>
+ <output>
+ <soap:body namespace="http://test.com/soap/v3/" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
+ </output>
+ </operation>
+ </binding>
+ <service name="CustomerService">
+ <port name="CustomerPort" binding="tns:CustomerBinding">
+ <soap:address location="test://"/>
+ </port>
+ </service>
+</definitions>