Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions ext/soap/php_encoding.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,16 @@ static void soap_add_xml_ref(zval *data, xmlNodePtr node)
}
}

static void soap_add_xml_ref_holder(zval *data, xmlNodePtr node)
{
if (SOAP_GLOBAL(ref_map)) {
zval holder;

array_init(&holder);
zend_hash_index_update(SOAP_GLOBAL(ref_map), (zend_ulong)node, &holder);
}
}

static xmlNodePtr master_to_xml_int(encodePtr encode, zval *data, int style, xmlNodePtr parent, int check_class_map)
{
xmlNodePtr node = NULL;
Expand Down Expand Up @@ -2536,6 +2546,9 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data)

ZVAL_NULL(ret);
FIND_XML_NULL(data, ret);
if (soap_check_xml_ref(ret, data)) {
return ret;
}

if (data &&
(attr = get_attribute(data->properties,"arrayType")) &&
Expand Down Expand Up @@ -2672,6 +2685,7 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data)
}

array_init(ret);
soap_add_xml_ref_holder(ret, data);
trav = data->children;
while (trav) {
if (trav->type == XML_ELEMENT_NODE) {
Expand Down Expand Up @@ -2729,6 +2743,7 @@ static zval *to_zval_array(zval *ret, encodeTypePtr type, xmlNodePtr data)
}
efree(dims);
efree(pos);
soap_add_xml_ref(ret, data);
return ret;
}

Expand Down Expand Up @@ -2798,9 +2813,13 @@ static zval *to_zval_map(zval *ret, encodeTypePtr type, xmlNodePtr data)

ZVAL_NULL(ret);
FIND_XML_NULL(data, ret);
if (soap_check_xml_ref(ret, data)) {
return ret;
}

if (data && data->children) {
array_init(ret);
soap_add_xml_ref_holder(ret, data);
trav = data->children;

trav = data->children;
Expand Down Expand Up @@ -2830,6 +2849,7 @@ static zval *to_zval_map(zval *ret, encodeTypePtr type, xmlNodePtr data)
zval_ptr_dtor(&key);
}
ENDFOREACH(trav);
soap_add_xml_ref(ret, data);
} else {
ZVAL_NULL(ret);
}
Expand Down
32 changes: 32 additions & 0 deletions ext/soap/tests/bugs/gh22984_1.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
--TEST--
GH-22984 (Native stack overflow while decoding a cyclic SOAP 1.1 href reference)
--EXTENSIONS--
soap
--FILE--
<?php
class TestSoapClient extends SoapClient {
public function __doRequest($request, $location, $action, $version, $one_way = false): ?string {
return <<<XML
<?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:probeResponse>
<ret id="a" SOAP-ENC:arrayType="xsd:anyType[1]">
<item href="#a"/>
</ret>
</ns1:probeResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
XML;
}
}

$client = new TestSoapClient(null, ['location' => 'test://', 'uri' => 'http://testuri.org', 'soap_version' => SOAP_1_1]);
var_dump($client->__soapCall('probe', []));
?>
--EXPECT--
array(1) {
[0]=>
array(0) {
}
}
47 changes: 47 additions & 0 deletions ext/soap/tests/bugs/gh22984_2.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
--TEST--
GH-22984 (Native stack overflow while decoding a cyclic SOAP 1.2 enc:ref reference)
--EXTENSIONS--
soap
--FILE--
<?php
class TestSoapClient extends SoapClient {
public function __doRequest($request, $location, $action, $version, $one_way = false): ?string {
return <<<XML
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:enc="http://www.w3.org/2003/05/soap-encoding" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="http://testuri.org">
<env:Body>
<ns1:probeResponse env:encodingStyle="http://www.w3.org/2003/05/soap-encoding">
<ret enc:id="a" xsi:type="enc:Array" enc:itemType="enc:Array" enc:arraySize="1">
<item enc:ref="#b" xsi:type="enc:Array" enc:itemType="enc:Array" enc:arraySize="1"/>
</ret>
<node enc:id="b" xsi:type="enc:Array" enc:itemType="enc:Array" enc:arraySize="1">
<item enc:ref="#a" xsi:type="enc:Array" enc:itemType="enc:Array" enc:arraySize="1"/>
</node>
</ns1:probeResponse>
</env:Body>
</env:Envelope>
XML;
}
}

$client = new TestSoapClient(null, ['location' => 'test://', 'uri' => 'http://testuri.org', 'soap_version' => SOAP_1_2]);
var_dump($client->__soapCall('probe', []));
?>
--EXPECT--
array(2) {
["ret"]=>
array(1) {
[0]=>
array(1) {
[0]=>
array(0) {
}
}
}
["node"]=>
array(1) {
[0]=>
array(0) {
}
}
}
35 changes: 35 additions & 0 deletions ext/soap/tests/bugs/gh22984_3.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
--TEST--
GH-22984 (Native stack overflow while decoding a cyclic reference inside an apache Map)
--EXTENSIONS--
soap
--FILE--
<?php
class TestSoapClient extends SoapClient {
public function __doRequest($request, $location, $action, $version, $one_way = false): ?string {
return <<<XML
<?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:apache="http://xml.apache.org/xml-soap" 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:probeResponse>
<ret id="a" xsi:type="apache:Map">
<item>
<key xsi:type="xsd:string">self</key>
<value href="#a"/>
</item>
</ret>
</ns1:probeResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
XML;
}
}

$client = new TestSoapClient(null, ['location' => 'test://', 'uri' => 'http://testuri.org', 'soap_version' => SOAP_1_1]);
var_dump($client->__soapCall('probe', []));
?>
--EXPECT--
array(1) {
["self"]=>
array(0) {
}
}
40 changes: 40 additions & 0 deletions ext/soap/tests/bugs/gh22984_4.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
--TEST--
GH-22984 (Native stack overflow while a SoapServer decodes a cyclic href reference)
--EXTENSIONS--
soap
--FILE--
<?php
$decoded = null;

function probe($a) {
global $decoded;
$decoded = $a;
return 1;
}

$request = <<<XML
<?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:probe>
<a id="a" SOAP-ENC:arrayType="xsd:anyType[1]">
<item href="#a"/>
</a>
</ns1:probe>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
XML;

$server = new SoapServer(null, ['uri' => 'http://testuri.org']);
$server->addFunction('probe');
$server->handle($request);
var_dump($decoded);
?>
--EXPECT--
<?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: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/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:probeResponse><return xsi:type="xsd:int">1</return></ns1:probeResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
array(1) {
[0]=>
array(0) {
}
}
Loading