Fix crash when an invalid callback function is passed to CURLMOPT_PUSHFUNCTION

Previously this caused a SIGABRT.

Closes GH-11639.
This commit is contained in:
Niels Dossche 2023-07-08 18:30:28 +02:00
parent bbe72f160d
commit 3ccd8d7866
3 changed files with 63 additions and 2 deletions

4
NEWS
View File

@ -13,6 +13,10 @@ PHP NEWS
(ilutov)
. Fixed use-of-uninitialized-value with ??= on assert. (ilutov)
- Curl:
. Fix crash when an invalid callback function is passed to
CURLMOPT_PUSHFUNCTION. (nielsdos)
- Date:
. Fixed bug GH-11368 (Date modify returns invalid datetime). (Derick)

View File

@ -382,6 +382,11 @@ static int _php_server_push_callback(CURL *parent_ch, CURL *easy, size_t num_hea
return rval;
}
if (UNEXPECTED(zend_fcall_info_init(&t->func_name, 0, &fci, &t->fci_cache, NULL, NULL) == FAILURE)) {
php_error_docref(NULL, E_WARNING, "Cannot call the CURLMOPT_PUSHFUNCTION");
return CURL_PUSH_OK;
}
parent = Z_CURL_P(pz_parent_ch);
ch = init_curl_handle_into_zval(&pz_ch);
@ -395,8 +400,6 @@ static int _php_server_push_callback(CURL *parent_ch, CURL *easy, size_t num_hea
add_next_index_string(&headers, header);
}
zend_fcall_info_init(&t->func_name, 0, &fci, &t->fci_cache, NULL, NULL);
zend_fcall_info_argn(
&fci, 3,
pz_parent_ch,

View File

@ -0,0 +1,54 @@
--TEST--
Test CURLMOPT_PUSHFUNCTION with non-existent callback function
--CREDITS--
Davey Shafik
Kévin Dunglas
Niels Dossche
--EXTENSIONS--
curl
--SKIPIF--
<?php
include 'skipif-nocaddy.inc';
$curl_version = curl_version();
if ($curl_version['version_number'] < 0x080100) {
exit("skip: test may crash with curl < 8.1.0");
}
?>
--FILE--
<?php
// Test adapted from curl_pushfunction.phpt
$mh = curl_multi_init();
curl_multi_setopt($mh, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
curl_multi_setopt($mh, CURLMOPT_PUSHFUNCTION, "nonexistent");
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://localhost/serverpush");
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_multi_add_handle($mh, $ch);
$active = null;
while(true) {
$status = curl_multi_exec($mh, $active);
do {
$info = curl_multi_info_read($mh);
if (false !== $info && $info['msg'] == CURLMSG_DONE) {
$handle = $info['handle'];
if ($handle !== null) {
curl_multi_remove_handle($mh, $handle);
curl_close($handle);
break 2;
}
}
} while ($info);
}
curl_multi_close($mh);
?>
--EXPECTF--
Warning: curl_multi_exec(): Cannot call the CURLMOPT_PUSHFUNCTION in %s on line %d