@@ -474,7 +474,9 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
474
474
475
475
zend_get_gc_buffer_add_zval (gc_buffer , & curl -> postfields );
476
476
if (curl -> handlers .read ) {
477
- zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .read -> func_name );
477
+ if (ZEND_FCC_INITIALIZED (curl -> handlers .read -> fcc )) {
478
+ zend_get_gc_buffer_add_fcc (gc_buffer , & curl -> handlers .read -> fcc );
479
+ }
478
480
zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .read -> stream );
479
481
}
480
482
@@ -766,53 +768,41 @@ static int curl_ssh_hostkeyfunction(void *clientp, int keytype, const char *key,
766
768
static size_t curl_read (char * data , size_t size , size_t nmemb , void * ctx )
767
769
{
768
770
php_curl * ch = (php_curl * )ctx ;
769
- php_curl_read * t = ch -> handlers .read ;
771
+ php_curl_read * read_handler = ch -> handlers .read ;
770
772
int length = 0 ;
771
773
772
- switch (t -> method ) {
774
+ switch (read_handler -> method ) {
773
775
case PHP_CURL_DIRECT :
774
- if (t -> fp ) {
775
- length = fread (data , size , nmemb , t -> fp );
776
+ if (read_handler -> fp ) {
777
+ length = fread (data , size , nmemb , read_handler -> fp );
776
778
}
777
779
break ;
778
780
case PHP_CURL_USER : {
779
781
zval argv [3 ];
780
782
zval retval ;
781
- zend_result error ;
782
- zend_fcall_info fci ;
783
783
784
784
GC_ADDREF (& ch -> std );
785
785
ZVAL_OBJ (& argv [0 ], & ch -> std );
786
- if (t -> res ) {
787
- GC_ADDREF (t -> res );
788
- ZVAL_RES (& argv [1 ], t -> res );
786
+ if (read_handler -> res ) {
787
+ GC_ADDREF (read_handler -> res );
788
+ ZVAL_RES (& argv [1 ], read_handler -> res );
789
789
} else {
790
790
ZVAL_NULL (& argv [1 ]);
791
791
}
792
792
ZVAL_LONG (& argv [2 ], (int )size * nmemb );
793
793
794
- fci .size = sizeof (fci );
795
- ZVAL_COPY_VALUE (& fci .function_name , & t -> func_name );
796
- fci .object = NULL ;
797
- fci .retval = & retval ;
798
- fci .param_count = 3 ;
799
- fci .params = argv ;
800
- fci .named_params = NULL ;
801
-
802
- ch -> in_callback = 1 ;
803
- error = zend_call_function (& fci , & t -> fci_cache );
804
- ch -> in_callback = 0 ;
805
- if (error == FAILURE ) {
806
- php_error_docref (NULL , E_WARNING , "Cannot call the CURLOPT_READFUNCTION" );
807
- length = CURL_READFUNC_ABORT ;
808
- } else if (!Z_ISUNDEF (retval )) {
794
+ ch -> in_callback = true;
795
+ zend_call_known_fcc (& read_handler -> fcc , & retval , /* param_count */ 3 , argv , /* named_params */ NULL );
796
+ ch -> in_callback = false;
797
+ if (!Z_ISUNDEF (retval )) {
809
798
_php_curl_verify_handlers (ch , /* reporterror */ true);
810
799
if (Z_TYPE (retval ) == IS_STRING ) {
811
800
length = MIN ((int ) (size * nmemb ), Z_STRLEN (retval ));
812
801
memcpy (data , Z_STRVAL (retval ), length );
813
802
} else if (Z_TYPE (retval ) == IS_LONG ) {
814
803
length = Z_LVAL_P (& retval );
815
804
}
805
+ // TODO Do type error if invalid type?
816
806
zval_ptr_dtor (& retval );
817
807
}
818
808
@@ -1212,8 +1202,8 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
1212
1202
ch -> handlers .read -> fp = source -> handlers .read -> fp ;
1213
1203
ch -> handlers .read -> res = source -> handlers .read -> res ;
1214
1204
1215
- if (! Z_ISUNDEF (source -> handlers .read -> func_name )) {
1216
- ZVAL_COPY ( & ch -> handlers .read -> func_name , & source -> handlers .read -> func_name );
1205
+ if (ZEND_FCC_INITIALIZED (source -> handlers .read -> fcc )) {
1206
+ zend_fcc_dup ( & source -> handlers .read -> fcc , & source -> handlers .read -> fcc );
1217
1207
}
1218
1208
if (ZEND_FCC_INITIALIZED (source -> handlers .write -> fcc )) {
1219
1209
zend_fcc_dup (& source -> handlers .write -> fcc , & source -> handlers .write -> fcc );
@@ -2111,6 +2101,16 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
2111
2101
break ;
2112
2102
}
2113
2103
2104
+ case CURLOPT_READFUNCTION :
2105
+ /* Check value is actually a callable and set it */
2106
+ const char option_name [] = "CURLOPT_READFUNCTION" ;
2107
+ bool result = php_curl_set_callable_handler (& ch -> handlers .read -> fcc , zvalue , is_array_config , option_name );
2108
+ if (!result ) {
2109
+ return FAILURE ;
2110
+ }
2111
+ ch -> handlers .read -> method = PHP_CURL_USER ;
2112
+ break ;
2113
+
2114
2114
case CURLOPT_PROGRESSFUNCTION : {
2115
2115
/* Check value is actually a callable and set it */
2116
2116
const char option_name [] = "CURLOPT_PROGRESSFUNCTION" ;
@@ -2161,15 +2161,6 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
2161
2161
}
2162
2162
#endif
2163
2163
2164
- case CURLOPT_READFUNCTION :
2165
- if (!Z_ISUNDEF (ch -> handlers .read -> func_name )) {
2166
- zval_ptr_dtor (& ch -> handlers .read -> func_name );
2167
- ch -> handlers .read -> fci_cache = empty_fcall_info_cache ;
2168
- }
2169
- ZVAL_COPY (& ch -> handlers .read -> func_name , zvalue );
2170
- ch -> handlers .read -> method = PHP_CURL_USER ;
2171
- break ;
2172
-
2173
2164
case CURLOPT_RETURNTRANSFER :
2174
2165
if (zend_is_true (zvalue )) {
2175
2166
ch -> handlers .write -> method = PHP_CURL_RETURN ;
@@ -2779,13 +2770,15 @@ static void curl_free_obj(zend_object *object)
2779
2770
}
2780
2771
2781
2772
smart_str_free (& ch -> handlers .write -> buf );
2782
- zval_ptr_dtor (& ch -> handlers .read -> func_name );
2783
2773
if (ZEND_FCC_INITIALIZED (ch -> handlers .write -> fcc )) {
2784
2774
zend_fcc_dtor (& ch -> handlers .write -> fcc );
2785
2775
}
2786
2776
if (ZEND_FCC_INITIALIZED (ch -> handlers .write_header -> fcc )) {
2787
2777
zend_fcc_dtor (& ch -> handlers .write_header -> fcc );
2788
2778
}
2779
+ if (ZEND_FCC_INITIALIZED (ch -> handlers .read -> fcc )) {
2780
+ zend_fcc_dtor (& ch -> handlers .read -> fcc );
2781
+ }
2789
2782
zval_ptr_dtor (& ch -> handlers .std_err );
2790
2783
if (ch -> header .str ) {
2791
2784
zend_string_release_ex (ch -> header .str , 0 );
0 commit comments