Skip to content

Commit

Permalink
Fix crash when an invalid callback function is passed to CURLMOPT_PUS…
Browse files Browse the repository at this point in the history
…HFUNCTION

Previously this caused a SIGABRT.

Closes GH-11639.
  • Loading branch information
nielsdos committed Jul 8, 2023
1 parent bbe72f1 commit 3ccd8d7
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 2 deletions.
4 changes: 4 additions & 0 deletions NEWS
Expand Up @@ -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)

Expand Down
7 changes: 5 additions & 2 deletions ext/curl/multi.c
Expand Up @@ -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);
Expand All @@ -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,
Expand Down
54 changes: 54 additions & 0 deletions ext/curl/tests/curl_pushfunction_nonexistent_callback.phpt
@@ -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

0 comments on commit 3ccd8d7

Please sign in to comment.