diff --git a/NEWS b/NEWS index ac01709f717ee..c25f71fa0b406 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,10 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| ?? ??? ????, PHP 8.2.26 +- Curl: + . Fixed bug GH-16302 (CurlMultiHandle holds a reference to CurlHandle if + curl_multi_add_handle fails). (timwolla) + - XMLReader: . Fixed bug GH-16292 (Segmentation fault in ext/xmlreader/php_xmlreader.c). (nielsdos) diff --git a/ext/curl/multi.c b/ext/curl/multi.c index 70cc7e0366410..41df6bcd7b1ed 100644 --- a/ext/curl/multi.c +++ b/ext/curl/multi.c @@ -97,12 +97,14 @@ PHP_FUNCTION(curl_multi_add_handle) _php_curl_cleanup_handle(ch); - Z_ADDREF_P(z_ch); - zend_llist_add_element(&mh->easyh, z_ch); - error = curl_multi_add_handle(mh->multi, ch->cp); SAVE_CURLM_ERROR(mh, error); + if (error == CURLM_OK) { + Z_ADDREF_P(z_ch); + zend_llist_add_element(&mh->easyh, z_ch); + } + RETURN_LONG((zend_long) error); } /* }}} */ @@ -164,9 +166,11 @@ PHP_FUNCTION(curl_multi_remove_handle) error = curl_multi_remove_handle(mh->multi, ch->cp); SAVE_CURLM_ERROR(mh, error); - RETVAL_LONG((zend_long) error); - zend_llist_del_element(&mh->easyh, z_ch, (int (*)(void *, void *))curl_compare_objects); + if (error == CURLM_OK) { + zend_llist_del_element(&mh->easyh, z_ch, (int (*)(void *, void *))curl_compare_objects); + } + RETURN_LONG((zend_long) error); } /* }}} */ diff --git a/ext/curl/tests/curl_multi_add_handle_lifecycle.phpt b/ext/curl/tests/curl_multi_add_handle_lifecycle.phpt new file mode 100644 index 0000000000000..3027f0c331521 --- /dev/null +++ b/ext/curl/tests/curl_multi_add_handle_lifecycle.phpt @@ -0,0 +1,49 @@ +--TEST-- +curl_multi_add_handle does not hold onto the handle on failure +--EXTENSIONS-- +curl +--FILE-- + $ch) { + curl_multi_remove_handle($mh, $ch); + unset($ch); + unset($toRemove[$i]); +} +echo "Removed", PHP_EOL; + +?> +--EXPECTF-- +Removing +MyClass::__destruct +MyClass::__destruct +Removed