Merge branch 'PHP-8.4'

* PHP-8.4:
  Fix GH-16318: Recursive array segfaults soap encoding
This commit is contained in:
Niels Dossche 2024-10-12 23:30:50 +02:00
commit e150b0b3a1
No known key found for this signature in database
GPG key ID: B8A8AD166DF0E2E5
2 changed files with 54 additions and 0 deletions

View file

@ -2149,6 +2149,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;
@ -2197,6 +2204,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) {
@ -2714,6 +2723,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);
@ -2741,6 +2757,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);

View 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