Skip to content

Commit

Permalink
Merge branch 'PHP-8.4'
Browse files Browse the repository at this point in the history
* PHP-8.4:
  curl: Prevent a CurlMultiHandle from holding onto a CurlHandle if `add_handle` fails (php#16302)
  • Loading branch information
TimWolla committed Oct 9, 2024
2 parents dd0ced3 + f2fbb75 commit b675db4
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
14 changes: 9 additions & 5 deletions ext/curl/multi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
/* }}} */
Expand Down Expand Up @@ -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);
}
/* }}} */

Expand Down
49 changes: 49 additions & 0 deletions ext/curl/tests/curl_multi_add_handle_lifecycle.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
--TEST--
curl_multi_add_handle does not hold onto the handle on failure
--EXTENSIONS--
curl
--FILE--
<?php

class MyClass {
public function __destruct() {
echo __METHOD__, PHP_EOL;
}
}

$urls = [
"file://".__DIR__."/curl_testdata1.txt",
"file://".__DIR__."/curl_testdata2.txt",
];

$mh = curl_multi_init();

$toRemove = [];
foreach ($urls as $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_PRIVATE, new MyClass());

if (curl_multi_add_handle($mh, $ch) == CURLM_OK) {
$toRemove[] = $ch;
}
if (curl_multi_add_handle($mh, $ch) == CURLM_OK) {
$toRemove[] = $ch;
}

unset($ch);
}

echo "Removing", PHP_EOL;
foreach ($toRemove as $i => $ch) {
curl_multi_remove_handle($mh, $ch);
unset($ch);
unset($toRemove[$i]);
}
echo "Removed", PHP_EOL;

?>
--EXPECTF--
Removing
MyClass::__destruct
MyClass::__destruct
Removed

0 comments on commit b675db4

Please sign in to comment.