diff --git a/NEWS b/NEWS index af896a7684b..0a4ceead58e 100644 --- a/NEWS +++ b/NEWS @@ -25,6 +25,10 @@ PHP NEWS return value check). (nielsdos, botovq) . Fix error return check of EVP_CIPHER_CTX_ctrl(). (nielsdos) +- SOAP: + . Fixed bug GH-18640 (heap-use-after-free ext/soap/php_encoding.c:299:32 + in soap_check_zval_ref). (nielsdos) + - Sockets: . Fix some potential crashes on incorrect argument value. (nielsdos) diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 57f92fa9a72..b829ce047a6 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -1949,6 +1949,11 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo sdlAttributePtr attr; zval *zattr, rv; + /* Attributes can't refer to other attributes as there's nothing to attach the href to. */ + HashTable **ref_map = &SOAP_GLOBAL(ref_map); + HashTable *old_ref_map = *ref_map; + *ref_map = NULL; + ZEND_HASH_FOREACH_PTR(sdlType->attributes, attr) { if (attr->name) { zattr = get_zval_property(data, attr->name, &rv); @@ -1978,6 +1983,8 @@ static xmlNodePtr to_xml_object(encodeTypePtr type, zval *data, int style, xmlNo } } } ZEND_HASH_FOREACH_END(); + + *ref_map = old_ref_map; } } if (style == SOAP_ENCODED) { @@ -3060,6 +3067,12 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP ret = xmlNewNode(NULL, BAD_CAST("BOGUS")); xmlAddChild(parent, ret); FIND_ZVAL_NULL(data, ret, style); + + /* Literals are unique and can't refer to other references via attributes. */ + HashTable **ref_map = &SOAP_GLOBAL(ref_map); + HashTable *old_ref_map = *ref_map; + *ref_map = NULL; + if (Z_TYPE_P(data) == IS_ARRAY) { zval *tmp; smart_str list = {0}; @@ -3134,6 +3147,7 @@ static xmlNodePtr to_xml_list(encodeTypePtr enc, zval *data, int style, xmlNodeP zval_ptr_dtor_str(&tmp); } } + *ref_map = old_ref_map; return ret; } diff --git a/ext/soap/tests/bugs/gh18640.phpt b/ext/soap/tests/bugs/gh18640.phpt new file mode 100644 index 00000000000..493659eca30 --- /dev/null +++ b/ext/soap/tests/bugs/gh18640.phpt @@ -0,0 +1,42 @@ +--TEST--- +GH-18640 (heap-use-after-free ext/soap/php_encoding.c:299:32 in soap_check_zval_ref) +--EXTENSIONS-- +soap +--CREDITS-- +YuanchengJiang +--FILE-- + 1, 'classmap' => ['logOnEvent' => 'LogOnEvent', 'events' => 'IVREvents']]); +$timestamp = new LogOnEvent(); // Bogus! +$logOffEvents[] = new LogOffEvent($timestamp); +$logOffEvents[] = new LogOffEvent($timestamp); +$ivrEvents = new IVREvents($logOffEvents); +$result = $soapClient->PostEvents($ivrEvents); + +class LogOffEvent { + function __construct(public $timestamp) { + $this->timestamp = $timestamp; + } +} + +class LogOnEvent { +} + +class IVREvents { + function __construct(public $logOffEvent) { + } +} +?> +--EXPECT-- +string(359) " + +"