Skip to content

Commit 9712506

Browse files
committed
Revert "ext/curl: Convert handlers.xferinfo to just be a FCC"
The test about the handle copy hangs This reverts commit 80ab6a2.
1 parent 80ab6a2 commit 9712506

File tree

4 files changed

+50
-48
lines changed

4 files changed

+50
-48
lines changed

ext/curl/curl_private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ typedef struct {
7373
php_curl_read *read;
7474
zval std_err;
7575
zend_fcall_info_cache progress;
76-
zend_fcall_info_cache xferinfo;
76+
php_curl_callback *xferinfo;
7777
php_curl_callback *fnmatch;
7878
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
7979
zend_fcall_info_cache sshhostkey;

ext/curl/interface.c

Lines changed: 38 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -491,8 +491,8 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
491491
zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.progress);
492492
}
493493

494-
if (ZEND_FCC_INITIALIZED(curl->handlers.xferinfo)) {
495-
zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.xferinfo);
494+
if (curl->handlers.xferinfo) {
495+
zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.xferinfo->func_name);
496496
}
497497

498498
if (curl->handlers.fnmatch) {
@@ -702,6 +702,7 @@ static size_t curl_progress(void *clientp, double dltotal, double dlnow, double
702702
static size_t curl_xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow)
703703
{
704704
php_curl *ch = (php_curl *)clientp;
705+
php_curl_callback *t = ch->handlers.xferinfo;
705706
size_t rval = 0;
706707

707708
#if PHP_CURL_DEBUG
@@ -711,6 +712,8 @@ static size_t curl_xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
711712

712713
zval argv[5];
713714
zval retval;
715+
zend_result error;
716+
zend_fcall_info fci;
714717

715718
GC_ADDREF(&ch->std);
716719
ZVAL_OBJ(&argv[0], &ch->std);
@@ -719,18 +722,25 @@ static size_t curl_xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
719722
ZVAL_LONG(&argv[3], ultotal);
720723
ZVAL_LONG(&argv[4], ulnow);
721724

722-
ch->in_callback = true;
723-
zend_call_known_fcc(&ch->handlers.xferinfo, &retval, /* param_count */ sizeof(argv), argv, /* named_params */ NULL);
724-
ch->in_callback = false;
725-
726-
if (!Z_ISUNDEF(retval)) {
727-
_php_curl_verify_handlers(ch, /* reporterror */ true);
728-
/* TODO Check callback returns an int or something castable to in */
729-
if (0 != zval_get_long(&retval)) {
730-
rval = 1;
731-
}
732-
}
725+
fci.size = sizeof(fci);
726+
ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
727+
fci.object = NULL;
728+
fci.retval = &retval;
729+
fci.param_count = 5;
730+
fci.params = argv;
731+
fci.named_params = NULL;
733732

733+
ch->in_callback = 1;
734+
error = zend_call_function(&fci, &t->fci_cache);
735+
ch->in_callback = 0;
736+
if (error == FAILURE) {
737+
php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_XFERINFOFUNCTION");
738+
} else if (!Z_ISUNDEF(retval)) {
739+
_php_curl_verify_handlers(ch, /* reporterror */ true);
740+
if (0 != zval_get_long(&retval)) {
741+
rval = 1;
742+
}
743+
}
734744
zval_ptr_dtor(&argv[0]);
735745
return rval;
736746
}
@@ -1024,7 +1034,7 @@ void init_curl_handle(php_curl *ch)
10241034
ch->handlers.write_header = ecalloc(1, sizeof(php_curl_write));
10251035
ch->handlers.read = ecalloc(1, sizeof(php_curl_read));
10261036
ch->handlers.progress = empty_fcall_info_cache;
1027-
ch->handlers.xferinfo = empty_fcall_info_cache;
1037+
ch->handlers.xferinfo = NULL;
10281038
ch->handlers.fnmatch = NULL;
10291039
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
10301040
ch->handlers.sshhostkey = empty_fcall_info_cache;
@@ -1208,7 +1218,7 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
12081218
curl_easy_setopt(ch->cp, CURLOPT_DEBUGDATA, (void *) ch);
12091219

12101220
php_curl_copy_fcc_with_option(ch, CURLOPT_PROGRESSDATA, &ch->handlers.progress, &source->handlers.progress);
1211-
php_curl_copy_fcc_with_option(ch, CURLOPT_XFERINFODATA, &ch->handlers.xferinfo, &source->handlers.xferinfo);
1221+
_php_copy_callback(ch, &ch->handlers.xferinfo, source->handlers.xferinfo, CURLOPT_XFERINFODATA);
12121222
_php_copy_callback(ch, &ch->handlers.fnmatch, source->handlers.fnmatch, CURLOPT_FNMATCH_DATA);
12131223
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
12141224
php_curl_copy_fcc_with_option(ch, CURLOPT_SSH_HOSTKEYDATA, &ch->handlers.sshhostkey, &source->handlers.sshhostkey);
@@ -2127,17 +2137,17 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
21272137
ch->handlers.write->method = PHP_CURL_USER;
21282138
break;
21292139

2130-
case CURLOPT_XFERINFOFUNCTION: {
2131-
/* Check value is actually a callable and set it */
2132-
const char option_name[] = "CURLOPT_XFERINFOFUNCTION";
2133-
bool result = php_curl_set_callable_handler(&ch->handlers.xferinfo, zvalue, is_array_config, option_name);
2134-
if (!result) {
2135-
return FAILURE;
2136-
}
2140+
case CURLOPT_XFERINFOFUNCTION:
21372141
curl_easy_setopt(ch->cp, CURLOPT_XFERINFOFUNCTION, curl_xferinfo);
21382142
curl_easy_setopt(ch->cp, CURLOPT_XFERINFODATA, ch);
2143+
if (ch->handlers.xferinfo == NULL) {
2144+
ch->handlers.xferinfo = ecalloc(1, sizeof(php_curl_callback));
2145+
} else if (!Z_ISUNDEF(ch->handlers.xferinfo->func_name)) {
2146+
zval_ptr_dtor(&ch->handlers.xferinfo->func_name);
2147+
ch->handlers.xferinfo->fci_cache = empty_fcall_info_cache;
2148+
}
2149+
ZVAL_COPY(&ch->handlers.xferinfo->func_name, zvalue);
21392150
break;
2140-
}
21412151

21422152
/* Curl off_t options */
21432153
case CURLOPT_MAX_RECV_SPEED_LARGE:
@@ -2779,9 +2789,7 @@ static void curl_free_obj(zend_object *object)
27792789
if (ZEND_FCC_INITIALIZED(ch->handlers.progress)) {
27802790
zend_fcc_dtor(&ch->handlers.progress);
27812791
}
2782-
if (ZEND_FCC_INITIALIZED(ch->handlers.xferinfo)) {
2783-
zend_fcc_dtor(&ch->handlers.xferinfo);
2784-
}
2792+
_php_curl_free_callback(ch->handlers.xferinfo);
27852793
_php_curl_free_callback(ch->handlers.fnmatch);
27862794
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
27872795
if (ZEND_FCC_INITIALIZED(ch->handlers.sshhostkey)) {
@@ -2854,9 +2862,10 @@ static void _php_curl_reset_handlers(php_curl *ch)
28542862
zend_fcc_dtor(&ch->handlers.progress);
28552863
}
28562864

2857-
if (ZEND_FCC_INITIALIZED(ch->handlers.xferinfo)) {
2858-
zend_fcc_dtor(&ch->handlers.xferinfo);
2859-
ch->handlers.xferinfo.function_handler = NULL;
2865+
if (ch->handlers.xferinfo) {
2866+
zval_ptr_dtor(&ch->handlers.xferinfo->func_name);
2867+
efree(ch->handlers.xferinfo);
2868+
ch->handlers.xferinfo = NULL;
28602869
}
28612870

28622871
if (ch->handlers.fnmatch) {

ext/curl/tests/curl_copy_handle_xferinfo.phpt

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,23 +4,19 @@ Test curl_copy_handle() with CURLOPT_XFERINFOFUNCTION
44
curl
55
--FILE--
66
<?php
7-
include 'server.inc';
8-
$host = curl_cli_server_start();
7+
include 'server.inc';
8+
$host = curl_cli_server_start();
99

10-
$url = "{$host}/get.inc";
11-
$ch = curl_init($url);
10+
$url = "{$host}/get.inc";
11+
$ch = curl_init($url);
1212

13-
function foo() {
14-
static $done = false; if (!$done) { echo "Download progress!\n"; $done = true; }
15-
}
16-
17-
curl_setopt($ch, CURLOPT_NOPROGRESS, 0);
18-
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
19-
curl_setopt($ch, CURLOPT_XFERINFOFUNCTION, 'foo');
20-
$ch2 = curl_copy_handle($ch);
21-
echo curl_exec($ch), PHP_EOL;
22-
unset($ch);
23-
echo curl_exec($ch2);
13+
curl_setopt($ch, CURLOPT_NOPROGRESS, 0);
14+
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
15+
curl_setopt($ch, CURLOPT_XFERINFOFUNCTION, function() { static $done = false; if (!$done) { echo "Download progress!\n"; $done = true; } });
16+
$ch2 = curl_copy_handle($ch);
17+
echo curl_exec($ch), PHP_EOL;
18+
unset($ch);
19+
echo curl_exec($ch2);
2420

2521
?>
2622
--EXPECT--

ext/curl/tests/curl_setopt_callables.phpt

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,10 @@ $url = "{$host}/get.inc";
2525
$ch = curl_init($url);
2626
testOption($ch, CURLOPT_PROGRESSFUNCTION);
2727
testOption($ch, CURLOPT_SSH_HOSTKEYFUNCTION);
28-
testOption($ch, CURLOPT_XFERINFOFUNCTION);
2928

3029
?>
3130
--EXPECT--
3231
TypeError: curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_PROGRESSFUNCTION, function "undefined" not found or invalid function name
3332
TypeError: curl_setopt_array(): Argument #2 ($options) must be a valid callback for option CURLOPT_PROGRESSFUNCTION, function "undefined" not found or invalid function name
3433
TypeError: curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_SSH_HOSTKEYFUNCTION, function "undefined" not found or invalid function name
3534
TypeError: curl_setopt_array(): Argument #2 ($options) must be a valid callback for option CURLOPT_SSH_HOSTKEYFUNCTION, function "undefined" not found or invalid function name
36-
TypeError: curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_XFERINFOFUNCTION, function "undefined" not found or invalid function name
37-
TypeError: curl_setopt_array(): Argument #2 ($options) must be a valid callback for option CURLOPT_XFERINFOFUNCTION, function "undefined" not found or invalid function name

0 commit comments

Comments
 (0)