Skip to content

Commit 16a3878

Browse files
committed
ext/curl: Convert handlers.fnmatch to just be a FCC
1 parent ea77ca8 commit 16a3878

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
@@ -496,8 +496,8 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
496496
zend_get_gc_buffer_add_fcc(gc_buffer, &curl->handlers.xferinfo);
497497
}
498498

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

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

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

640-
fci.size = sizeof(fci);
641-
ZVAL_COPY_VALUE(&fci.function_name, &t->func_name);
642-
fci.object = NULL;
643-
fci.retval = &retval;
644-
fci.param_count = 3;
645-
fci.params = argv;
646-
fci.named_params = NULL;
647-
648-
ch->in_callback = 1;
649-
error = zend_call_function(&fci, &t->fci_cache);
650-
ch->in_callback = 0;
651-
if (error == FAILURE) {
652-
php_error_docref(NULL, E_WARNING, "Cannot call the CURLOPT_FNMATCH_FUNCTION");
653-
} else if (!Z_ISUNDEF(retval)) {
637+
ch->in_callback = true;
638+
zend_call_known_fcc(&ch->handlers.fnmatch, &retval, /* param_count */ 3, argv, /* named_params */ NULL);
639+
ch->in_callback = false;
640+
641+
if (!Z_ISUNDEF(retval)) {
654642
_php_curl_verify_handlers(ch, /* reporterror */ true);
643+
/* TODO Check callback returns an int or something castable to int */
655644
rval = zval_get_long(&retval);
656645
}
657646
zval_ptr_dtor(&argv[0]);
@@ -1088,7 +1077,7 @@ void init_curl_handle(php_curl *ch)
10881077
ch->handlers.read = ecalloc(1, sizeof(php_curl_read));
10891078
ch->handlers.progress = empty_fcall_info_cache;
10901079
ch->handlers.xferinfo = empty_fcall_info_cache;
1091-
ch->handlers.fnmatch = NULL;
1080+
ch->handlers.fnmatch = empty_fcall_info_cache;
10921081
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
10931082
ch->handlers.sshhostkey = empty_fcall_info_cache;
10941083
#endif
@@ -1212,17 +1201,6 @@ PHP_FUNCTION(curl_init)
12121201
}
12131202
/* }}} */
12141203

1215-
static void _php_copy_callback(php_curl *ch, php_curl_callback **new_callback, php_curl_callback *source_callback, CURLoption option)
1216-
{
1217-
if (source_callback) {
1218-
*new_callback = ecalloc(1, sizeof(php_curl_callback));
1219-
if (!Z_ISUNDEF(source_callback->func_name)) {
1220-
ZVAL_COPY(&(*new_callback)->func_name, &source_callback->func_name);
1221-
}
1222-
curl_easy_setopt(ch->cp, option, (void *) ch);
1223-
}
1224-
}
1225-
12261204
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)
12271205
{
12281206
if (ZEND_FCC_INITIALIZED(*source_fcc)) {
@@ -1272,7 +1250,7 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
12721250

12731251
php_curl_copy_fcc_with_option(ch, CURLOPT_PROGRESSDATA, &ch->handlers.progress, &source->handlers.progress);
12741252
php_curl_copy_fcc_with_option(ch, CURLOPT_XFERINFODATA, &ch->handlers.xferinfo, &source->handlers.xferinfo);
1275-
_php_copy_callback(ch, &ch->handlers.fnmatch, source->handlers.fnmatch, CURLOPT_FNMATCH_DATA);
1253+
php_curl_copy_fcc_with_option(ch, CURLOPT_FNMATCH_DATA, &ch->handlers.fnmatch, &source->handlers.fnmatch);
12761254
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
12771255
php_curl_copy_fcc_with_option(ch, CURLOPT_SSH_HOSTKEYDATA, &ch->handlers.sshhostkey, &source->handlers.sshhostkey);
12781256
#endif
@@ -2162,6 +2140,18 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
21622140
break;
21632141
}
21642142

2143+
case CURLOPT_FNMATCH_FUNCTION: {
2144+
/* Check value is actually a callable and set it */
2145+
const char option_name[] = "CURLOPT_FNMATCH_FUNCTION";
2146+
bool result = php_curl_set_callable_handler(&ch->handlers.fnmatch, zvalue, is_array_config, option_name);
2147+
if (!result) {
2148+
return FAILURE;
2149+
}
2150+
curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_FUNCTION, curl_fnmatch);
2151+
curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_DATA, ch);
2152+
break;
2153+
}
2154+
21652155
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
21662156
case CURLOPT_SSH_HOSTKEYFUNCTION: {
21672157
/* Check value is actually a callable and set it */
@@ -2271,18 +2261,6 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
22712261
}
22722262
break;
22732263

2274-
case CURLOPT_FNMATCH_FUNCTION:
2275-
curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_FUNCTION, curl_fnmatch);
2276-
curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_DATA, ch);
2277-
if (ch->handlers.fnmatch == NULL) {
2278-
ch->handlers.fnmatch = ecalloc(1, sizeof(php_curl_callback));
2279-
} else if (!Z_ISUNDEF(ch->handlers.fnmatch->func_name)) {
2280-
zval_ptr_dtor(&ch->handlers.fnmatch->func_name);
2281-
ch->handlers.fnmatch->fci_cache = empty_fcall_info_cache;
2282-
}
2283-
ZVAL_COPY(&ch->handlers.fnmatch->func_name, zvalue);
2284-
break;
2285-
22862264
/* Curl blob options */
22872265
#if LIBCURL_VERSION_NUM >= 0x074700 /* Available since 7.71.0 */
22882266
case CURLOPT_ISSUERCERT_BLOB:
@@ -2771,14 +2749,6 @@ PHP_FUNCTION(curl_close)
27712749
}
27722750
/* }}} */
27732751

2774-
static void _php_curl_free_callback(php_curl_callback* callback)
2775-
{
2776-
if (callback) {
2777-
zval_ptr_dtor(&callback->func_name);
2778-
efree(callback);
2779-
}
2780-
}
2781-
27822752
static void curl_free_obj(zend_object *object)
27832753
{
27842754
php_curl *ch = curl_from_obj(object);
@@ -2845,7 +2815,9 @@ static void curl_free_obj(zend_object *object)
28452815
if (ZEND_FCC_INITIALIZED(ch->handlers.xferinfo)) {
28462816
zend_fcc_dtor(&ch->handlers.xferinfo);
28472817
}
2848-
_php_curl_free_callback(ch->handlers.fnmatch);
2818+
if (ZEND_FCC_INITIALIZED(ch->handlers.fnmatch)) {
2819+
zend_fcc_dtor(&ch->handlers.fnmatch);
2820+
}
28492821
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
28502822
if (ZEND_FCC_INITIALIZED(ch->handlers.sshhostkey)) {
28512823
zend_fcc_dtor(&ch->handlers.sshhostkey);
@@ -2922,10 +2894,8 @@ static void _php_curl_reset_handlers(php_curl *ch)
29222894
ch->handlers.xferinfo.function_handler = NULL;
29232895
}
29242896

2925-
if (ch->handlers.fnmatch) {
2926-
zval_ptr_dtor(&ch->handlers.fnmatch->func_name);
2927-
efree(ch->handlers.fnmatch);
2928-
ch->handlers.fnmatch = NULL;
2897+
if (ZEND_FCC_INITIALIZED(ch->handlers.fnmatch)) {
2898+
zend_fcc_dtor(&ch->handlers.fnmatch);
29292899
}
29302900

29312901
#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)