Skip to content

Commit 3ccd8d7

Browse files
committed
Fix crash when an invalid callback function is passed to CURLMOPT_PUSHFUNCTION
Previously this caused a SIGABRT. Closes GH-11639.
1 parent bbe72f1 commit 3ccd8d7

File tree

3 files changed

+63
-2
lines changed

3 files changed

+63
-2
lines changed

NEWS

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ PHP NEWS
1313
(ilutov)
1414
. Fixed use-of-uninitialized-value with ??= on assert. (ilutov)
1515

16+
- Curl:
17+
. Fix crash when an invalid callback function is passed to
18+
CURLMOPT_PUSHFUNCTION. (nielsdos)
19+
1620
- Date:
1721
. Fixed bug GH-11368 (Date modify returns invalid datetime). (Derick)
1822

ext/curl/multi.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,11 @@ static int _php_server_push_callback(CURL *parent_ch, CURL *easy, size_t num_hea
382382
return rval;
383383
}
384384

385+
if (UNEXPECTED(zend_fcall_info_init(&t->func_name, 0, &fci, &t->fci_cache, NULL, NULL) == FAILURE)) {
386+
php_error_docref(NULL, E_WARNING, "Cannot call the CURLMOPT_PUSHFUNCTION");
387+
return CURL_PUSH_OK;
388+
}
389+
385390
parent = Z_CURL_P(pz_parent_ch);
386391

387392
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
395400
add_next_index_string(&headers, header);
396401
}
397402

398-
zend_fcall_info_init(&t->func_name, 0, &fci, &t->fci_cache, NULL, NULL);
399-
400403
zend_fcall_info_argn(
401404
&fci, 3,
402405
pz_parent_ch,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
--TEST--
2+
Test CURLMOPT_PUSHFUNCTION with non-existent callback function
3+
--CREDITS--
4+
Davey Shafik
5+
Kévin Dunglas
6+
Niels Dossche
7+
--EXTENSIONS--
8+
curl
9+
--SKIPIF--
10+
<?php
11+
include 'skipif-nocaddy.inc';
12+
13+
$curl_version = curl_version();
14+
if ($curl_version['version_number'] < 0x080100) {
15+
exit("skip: test may crash with curl < 8.1.0");
16+
}
17+
?>
18+
--FILE--
19+
<?php
20+
// Test adapted from curl_pushfunction.phpt
21+
22+
$mh = curl_multi_init();
23+
24+
curl_multi_setopt($mh, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
25+
curl_multi_setopt($mh, CURLMOPT_PUSHFUNCTION, "nonexistent");
26+
27+
$ch = curl_init();
28+
curl_setopt($ch, CURLOPT_URL, "https://localhost/serverpush");
29+
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
30+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
31+
32+
curl_multi_add_handle($mh, $ch);
33+
34+
$active = null;
35+
while(true) {
36+
$status = curl_multi_exec($mh, $active);
37+
38+
do {
39+
$info = curl_multi_info_read($mh);
40+
if (false !== $info && $info['msg'] == CURLMSG_DONE) {
41+
$handle = $info['handle'];
42+
if ($handle !== null) {
43+
curl_multi_remove_handle($mh, $handle);
44+
curl_close($handle);
45+
break 2;
46+
}
47+
}
48+
} while ($info);
49+
}
50+
51+
curl_multi_close($mh);
52+
?>
53+
--EXPECTF--
54+
Warning: curl_multi_exec(): Cannot call the CURLMOPT_PUSHFUNCTION in %s on line %d

0 commit comments

Comments
 (0)