mirror of
https://github.com/php/php-src.git
synced 2026-03-24 08:12:21 +01:00
Fix GH-16318: Recursive array segfaults soap encoding
This adds recursion protection to the array encoders. Closes GH-16347.
This commit is contained in:
3
NEWS
3
NEWS
@@ -37,6 +37,9 @@ PHP NEWS
|
||||
. Fixed bug GH-16385 (Unexpected null returned by session_set_cookie_params).
|
||||
(nielsdos)
|
||||
|
||||
- SOAP:
|
||||
. Fixed bug GH-16318 (Recursive array segfaults soap encoding). (nielsdos)
|
||||
|
||||
- Sockets:
|
||||
. Fixed bug with overflow socket_recvfrom $length argument. (David Carlier)
|
||||
|
||||
|
||||
@@ -2136,6 +2136,13 @@ static void add_xml_array_elements(xmlNodePtr xmlParam,
|
||||
xmlNodePtr xparam;
|
||||
|
||||
if (data && Z_TYPE_P(data) == IS_ARRAY) {
|
||||
if (UNEXPECTED(Z_IS_RECURSIVE_P(data))) {
|
||||
zend_value_error("Recursive array cannot be encoded");
|
||||
return;
|
||||
}
|
||||
|
||||
GC_TRY_PROTECT_RECURSION(Z_ARRVAL_P(data));
|
||||
|
||||
ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL_P(data), zdata) {
|
||||
if (j >= dims[0]) {
|
||||
break;
|
||||
@@ -2184,6 +2191,8 @@ static void add_xml_array_elements(xmlNodePtr xmlParam,
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
GC_TRY_UNPROTECT_RECURSION(Z_ARRVAL_P(data));
|
||||
} else {
|
||||
for (j=0; j<dims[0]; j++) {
|
||||
if (dimension == 1) {
|
||||
@@ -2701,6 +2710,13 @@ static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodeP
|
||||
FIND_ZVAL_NULL(data, xmlParam, style);
|
||||
|
||||
if (Z_TYPE_P(data) == IS_ARRAY) {
|
||||
if (UNEXPECTED(Z_IS_RECURSIVE_P(data))) {
|
||||
zend_value_error("Recursive array cannot be encoded");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GC_TRY_PROTECT_RECURSION(Z_ARRVAL_P(data));
|
||||
|
||||
ZEND_HASH_FOREACH_KEY_VAL_IND(Z_ARRVAL_P(data), int_val, key_val, temp_data) {
|
||||
item = xmlNewNode(NULL, BAD_CAST("item"));
|
||||
xmlAddChild(xmlParam, item);
|
||||
@@ -2728,6 +2744,8 @@ static xmlNodePtr to_xml_map(encodeTypePtr type, zval *data, int style, xmlNodeP
|
||||
xparam = master_to_xml(get_conversion(Z_TYPE_P(temp_data)), temp_data, style, item);
|
||||
xmlNodeSetName(xparam, BAD_CAST("value"));
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
GC_TRY_UNPROTECT_RECURSION(Z_ARRVAL_P(data));
|
||||
}
|
||||
if (style == SOAP_ENCODED) {
|
||||
set_ns_and_type(xmlParam, type);
|
||||
|
||||
36
ext/soap/tests/gh16318.phpt
Normal file
36
ext/soap/tests/gh16318.phpt
Normal file
@@ -0,0 +1,36 @@
|
||||
--TEST--
|
||||
GH-16318 (Recursive array segfaults soap encoding)
|
||||
--EXTENSIONS--
|
||||
soap
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
// SOAP-ENC array
|
||||
$tmp =& $test1;
|
||||
$test1[] = $tmp;
|
||||
|
||||
// map array
|
||||
$test2 = [];
|
||||
$test2["a"] = "a";
|
||||
$test2[] =& $test2;
|
||||
|
||||
class TestSoapClient extends SoapClient {
|
||||
public function __doRequest(string $request, string $location, string $action, int $version, bool $oneWay = false): ?string
|
||||
{
|
||||
die($request);
|
||||
}
|
||||
}
|
||||
$client = new TestSoapClient(NULL,array("location"=>"test://","uri"=>"http://soapinterop.org/","trace"=>1,"exceptions"=>0));
|
||||
|
||||
foreach ([$test1, $test2] as $test) {
|
||||
try {
|
||||
$client->__soapCall("echoStructArray", array($test), array("soapaction"=>"http://soapinterop.org/","uri"=>"http://soapinterop.org/"));
|
||||
} catch (ValueError $e) {
|
||||
echo $e->getMessage(), "\n";
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
||||
--EXPECT--
|
||||
Recursive array cannot be encoded
|
||||
Recursive array cannot be encoded
|
||||
Reference in New Issue
Block a user