Skip to content

Commit 2cf81fe

Browse files
committed
ext/curl: Convert handlers.fnmatch to just be a FCC
1 parent d12cc2a commit 2cf81fe

File tree

3 files changed

+31
-58
lines changed

3 files changed

+31
-58
lines changed

ext/curl/curl_private.h

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

ext/curl/interface.c

Lines changed: 27 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -495,8 +495,8 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
495495
zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.xferinfo);
496496
}
497497

498-
if (curl->handlers.fnmatch) {
499-
zend_get_gc_buffer_add_zval(gc_buffer, &curl->handlers.fnmatch->func_name);
498+
if (ZEND_FCC_INITIALIZED(curl->handlers.fnmatch)) {
499+
zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.fnmatch);
500500
}
501501

502502
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
@@ -624,33 +624,22 @@ static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx)
624624
static int curl_fnmatch(void *ctx, const char *pattern, const char *string)
625625
{
626626
php_curl *ch = (php_curl *) ctx;
627-
php_curl_callback *t = ch->handlers.fnmatch;
628627
int rval = CURL_FNMATCHFUNC_FAIL;
629628
zval argv[3];
630629
zval retval;
631-
zend_result error;
632-
zend_fcall_info fci;
633630

634631
GC_ADDREF(&ch->std);
635632
ZVAL_OBJ(&argv[0], &ch->std);
636633
ZVAL_STRING(&argv[1], pattern);
637634
ZVAL_STRING(&argv[2], string);
638635

639-
fci.size = sizeof(fci);
640-
ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
641-
fci.object = NULL;
642-
fci.retval = &retval;
643-
fci.param_count = 3;
644-
fci.params = argv;
645-
fci.named_params = NULL;
646-
647-
ch->in_callback = 1;
648-
error = zend_call_function(&fci, &t->fci_cache);
649-
ch->in_callback = 0;
650-
if (error == FAILURE) {
651-
php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_FNMATCH_FUNCTION");
652-
} else if (!Z_ISUNDEF(retval)) {
636+
ch->in_callback = true;
637+
zend_call_known_fcc(&ch->handlers.fnmatch, &retval, /* param_count */ 3, argv, /* named_params */ NULL);
638+
ch->in_callback = false;
639+
640+
if (!Z_ISUNDEF(retval)) {
653641
_php_curl_verify_handlers(ch, /* reporterror */ true);
642+
/* TODO Check callback returns an int or something castable to int */
654643
rval = zval_get_long(&retval);
655644
}
656645
zval_ptr_dtor(&argv[0]);
@@ -1025,7 +1014,7 @@ void init_curl_handle(php_curl *ch)
10251014
ch->handlers.read = ecalloc(1, sizeof(php_curl_read));
10261015
ch->handlers.progress = empty_fcall_info_cache;
10271016
ch->handlers.xferinfo = empty_fcall_info_cache;
1028-
ch->handlers.fnmatch = NULL;
1017+
ch->handlers.fnmatch = empty_fcall_info_cache;
10291018
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
10301019
ch->handlers.sshhostkey = empty_fcall_info_cache;
10311020
#endif
@@ -1149,17 +1138,6 @@ PHP_FUNCTION(curl_init)
11491138
}
11501139
/* }}} */
11511140

1152-
static void _php_copy_callback(php_curl *ch, php_curl_callback **new_callback, php_curl_callback *source_callback, CURLoption option)
1153-
{
1154-
if (source_callback) {
1155-
*new_callback = ecalloc(1, sizeof(php_curl_callback));
1156-
if (!Z_ISUNDEF(source_callback->func_name)) {
1157-
ZVAL_COPY(&(*new_callback)->func_name, &source_callback->func_name);
1158-
}
1159-
curl_easy_setopt(ch->cp, option, (void *) ch);
1160-
}
1161-
}
1162-
11631141
static void php_curl_copy_fcc_with_option(php_curl *ch, CURLoption option, zend_fcall_info_cache *target_fcc, zend_fcall_info_cache *source_fcc)
11641142
{
11651143
if (ZEND_FCC_INITIALIZED(*source_fcc)) {
@@ -1209,7 +1187,7 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
12091187

12101188
php_curl_copy_fcc_with_option(ch, CURLOPT_PROGRESSDATA, &ch->handlers.progress, &source->handlers.progress);
12111189
php_curl_copy_fcc_with_option(ch, CURLOPT_XFERINFODATA, &ch->handlers.xferinfo, &source->handlers.xferinfo);
1212-
_php_copy_callback(ch, &ch->handlers.fnmatch, source->handlers.fnmatch, CURLOPT_FNMATCH_DATA);
1190+
php_curl_copy_fcc_with_option(ch, CURLOPT_FNMATCH_DATA, &ch->handlers.fnmatch, &source->handlers.fnmatch);
12131191
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
12141192
php_curl_copy_fcc_with_option(ch, CURLOPT_SSH_HOSTKEYDATA, &ch->handlers.sshhostkey, &source->handlers.sshhostkey);
12151193
#endif
@@ -2099,6 +2077,18 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
20992077
break;
21002078
}
21012079

2080+
case CURLOPT_FNMATCH_FUNCTION: {
2081+
/* Check value is actually a callable and set it */
2082+
const char option_name[] = "CURLOPT_FNMATCH_FUNCTION";
2083+
bool result = php_curl_set_callable_handler(&ch->handlers.fnmatch, zvalue, is_array_config, option_name);
2084+
if (!result) {
2085+
return FAILURE;
2086+
}
2087+
curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_FUNCTION, curl_fnmatch);
2088+
curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_DATA, ch);
2089+
break;
2090+
}
2091+
21022092
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
21032093
case CURLOPT_SSH_HOSTKEYFUNCTION: {
21042094
/* Check value is actually a callable and set it */
@@ -2208,18 +2198,6 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
22082198
}
22092199
break;
22102200

2211-
case CURLOPT_FNMATCH_FUNCTION:
2212-
curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_FUNCTION, curl_fnmatch);
2213-
curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_DATA, ch);
2214-
if (ch->handlers.fnmatch == NULL) {
2215-
ch->handlers.fnmatch = ecalloc(1, sizeof(php_curl_callback));
2216-
} else if (!Z_ISUNDEF(ch->handlers.fnmatch->func_name)) {
2217-
zval_ptr_dtor(&ch->handlers.fnmatch->func_name);
2218-
ch->handlers.fnmatch->fci_cache = empty_fcall_info_cache;
2219-
}
2220-
ZVAL_COPY(&ch->handlers.fnmatch->func_name, zvalue);
2221-
break;
2222-
22232201
/* Curl blob options */
22242202
#if LIBCURL_VERSION_NUM >= 0x074700 /* Available since 7.71.0 */
22252203
case CURLOPT_ISSUERCERT_BLOB:
@@ -2708,14 +2686,6 @@ PHP_FUNCTION(curl_close)
27082686
}
27092687
/* }}} */
27102688

2711-
static void _php_curl_free_callback(php_curl_callback* callback)
2712-
{
2713-
if (callback) {
2714-
zval_ptr_dtor(&callback->func_name);
2715-
efree(callback);
2716-
}
2717-
}
2718-
27192689
static void curl_free_obj(zend_object *object)
27202690
{
27212691
php_curl *ch = curl_from_obj(object);
@@ -2782,7 +2752,9 @@ static void curl_free_obj(zend_object *object)
27822752
if (ZEND_FCC_INITIALIZED(ch->handlers.xferinfo)) {
27832753
zend_fcc_dtor(&ch->handlers.xferinfo);
27842754
}
2785-
_php_curl_free_callback(ch->handlers.fnmatch);
2755+
if (ZEND_FCC_INITIALIZED(ch->handlers.fnmatch)) {
2756+
zend_fcc_dtor(&ch->handlers.fnmatch);
2757+
}
27862758
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
27872759
if (ZEND_FCC_INITIALIZED(ch->handlers.sshhostkey)) {
27882760
zend_fcc_dtor(&ch->handlers.sshhostkey);
@@ -2859,10 +2831,8 @@ static void _php_curl_reset_handlers(php_curl *ch)
28592831
ch->handlers.xferinfo.function_handler = NULL;
28602832
}
28612833

2862-
if (ch->handlers.fnmatch) {
2863-
zval_ptr_dtor(&ch->handlers.fnmatch->func_name);
2864-
efree(ch->handlers.fnmatch);
2865-
ch->handlers.fnmatch = NULL;
2834+
if (ZEND_FCC_INITIALIZED(ch->handlers.fnmatch)) {
2835+
zend_fcc_dtor(&ch->handlers.fnmatch);
28662836
}
28672837

28682838
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */

ext/curl/tests/curl_setopt_callables.phpt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ $ch = curl_init($url);
2626
testOption($ch, CURLOPT_PROGRESSFUNCTION);
2727
testOption($ch, CURLOPT_SSH_HOSTKEYFUNCTION);
2828
testOption($ch, CURLOPT_XFERINFOFUNCTION);
29+
testOption($ch, CURLOPT_FNMATCH_FUNCTION);
2930

3031
?>
3132
--EXPECT--
@@ -35,3 +36,5 @@ TypeError: curl_setopt(): Argument #3 ($value) must be a valid callback for opti
3536
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
3637
TypeError: curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_XFERINFOFUNCTION, function "undefined" not found or invalid function name
3738
TypeError: curl_setopt_array(): Argument #2 ($options) must be a valid callback for option CURLOPT_XFERINFOFUNCTION, function "undefined" not found or invalid function name
39+
TypeError: curl_setopt(): Argument #3 ($value) must be a valid callback for option CURLOPT_FNMATCH_FUNCTION, function "undefined" not found or invalid function name
40+
TypeError: curl_setopt_array(): Argument #2 ($options) must be a valid callback for option CURLOPT_FNMATCH_FUNCTION, function "undefined" not found or invalid function name

0 commit comments

Comments
 (0)