@@ -473,7 +473,9 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
473
473
474
474
zend_get_gc_buffer_add_zval (gc_buffer , & curl -> postfields );
475
475
if (curl -> handlers .read ) {
476
- zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .read -> func_name );
476
+ if (ZEND_FCC_INITIALIZED (curl -> handlers .read -> fcc )) {
477
+ zend_get_gc_buffer_add_fcc (gc_buffer , & curl -> handlers .read -> fcc );
478
+ }
477
479
zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .read -> stream );
478
480
}
479
481
@@ -765,53 +767,41 @@ static int curl_ssh_hostkeyfunction(void *clientp, int keytype, const char *key,
765
767
static size_t curl_read (char * data , size_t size , size_t nmemb , void * ctx )
766
768
{
767
769
php_curl * ch = (php_curl * )ctx ;
768
- php_curl_read * t = ch -> handlers .read ;
770
+ php_curl_read * read_handler = ch -> handlers .read ;
769
771
int length = 0 ;
770
772
771
- switch (t -> method ) {
773
+ switch (read_handler -> method ) {
772
774
case PHP_CURL_DIRECT :
773
- if (t -> fp ) {
774
- length = fread (data , size , nmemb , t -> fp );
775
+ if (read_handler -> fp ) {
776
+ length = fread (data , size , nmemb , read_handler -> fp );
775
777
}
776
778
break ;
777
779
case PHP_CURL_USER : {
778
780
zval argv [3 ];
779
781
zval retval ;
780
- zend_result error ;
781
- zend_fcall_info fci ;
782
782
783
783
GC_ADDREF (& ch -> std );
784
784
ZVAL_OBJ (& argv [0 ], & ch -> std );
785
- if (t -> res ) {
786
- GC_ADDREF (t -> res );
787
- ZVAL_RES (& argv [1 ], t -> res );
785
+ if (read_handler -> res ) {
786
+ GC_ADDREF (read_handler -> res );
787
+ ZVAL_RES (& argv [1 ], read_handler -> res );
788
788
} else {
789
789
ZVAL_NULL (& argv [1 ]);
790
790
}
791
791
ZVAL_LONG (& argv [2 ], (int )size * nmemb );
792
792
793
- fci .size = sizeof (fci );
794
- ZVAL_COPY_VALUE (& fci .function_name , & t -> func_name );
795
- fci .object = NULL ;
796
- fci .retval = & retval ;
797
- fci .param_count = 3 ;
798
- fci .params = argv ;
799
- fci .named_params = NULL ;
800
-
801
- ch -> in_callback = 1 ;
802
- error = zend_call_function (& fci , & t -> fci_cache );
803
- ch -> in_callback = 0 ;
804
- if (error == FAILURE ) {
805
- php_error_docref (NULL , E_WARNING , "Cannot call the CURLOPT_READFUNCTION" );
806
- length = CURL_READFUNC_ABORT ;
807
- } else if (!Z_ISUNDEF (retval )) {
793
+ ch -> in_callback = true;
794
+ zend_call_known_fcc (& read_handler -> fcc , & retval , /* param_count */ 3 , argv , /* named_params */ NULL );
795
+ ch -> in_callback = false;
796
+ if (!Z_ISUNDEF (retval )) {
808
797
_php_curl_verify_handlers (ch , /* reporterror */ true);
809
798
if (Z_TYPE (retval ) == IS_STRING ) {
810
799
length = MIN ((int ) (size * nmemb ), Z_STRLEN (retval ));
811
800
memcpy (data , Z_STRVAL (retval ), length );
812
801
} else if (Z_TYPE (retval ) == IS_LONG ) {
813
802
length = Z_LVAL_P (& retval );
814
803
}
804
+ // TODO Do type error if invalid type?
815
805
zval_ptr_dtor (& retval );
816
806
}
817
807
@@ -1149,8 +1139,8 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
1149
1139
ch -> handlers .read -> fp = source -> handlers .read -> fp ;
1150
1140
ch -> handlers .read -> res = source -> handlers .read -> res ;
1151
1141
1152
- if (! Z_ISUNDEF (source -> handlers .read -> func_name )) {
1153
- ZVAL_COPY ( & ch -> handlers .read -> func_name , & source -> handlers .read -> func_name );
1142
+ if (ZEND_FCC_INITIALIZED (source -> handlers .read -> fcc )) {
1143
+ zend_fcc_dup ( & source -> handlers .read -> fcc , & source -> handlers .read -> fcc );
1154
1144
}
1155
1145
if (ZEND_FCC_INITIALIZED (source -> handlers .write -> fcc )) {
1156
1146
zend_fcc_dup (& source -> handlers .write -> fcc , & source -> handlers .write -> fcc );
@@ -2048,6 +2038,16 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
2048
2038
break ;
2049
2039
}
2050
2040
2041
+ case CURLOPT_READFUNCTION :
2042
+ /* Check value is actually a callable and set it */
2043
+ const char option_name [] = "CURLOPT_READFUNCTION" ;
2044
+ bool result = php_curl_set_callable_handler (& ch -> handlers .read -> fcc , zvalue , is_array_config , option_name );
2045
+ if (!result ) {
2046
+ return FAILURE ;
2047
+ }
2048
+ ch -> handlers .read -> method = PHP_CURL_USER ;
2049
+ break ;
2050
+
2051
2051
case CURLOPT_PROGRESSFUNCTION : {
2052
2052
/* Check value is actually a callable and set it */
2053
2053
const char option_name [] = "CURLOPT_PROGRESSFUNCTION" ;
@@ -2098,15 +2098,6 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
2098
2098
}
2099
2099
#endif
2100
2100
2101
- case CURLOPT_READFUNCTION :
2102
- if (!Z_ISUNDEF (ch -> handlers .read -> func_name )) {
2103
- zval_ptr_dtor (& ch -> handlers .read -> func_name );
2104
- ch -> handlers .read -> fci_cache = empty_fcall_info_cache ;
2105
- }
2106
- ZVAL_COPY (& ch -> handlers .read -> func_name , zvalue );
2107
- ch -> handlers .read -> method = PHP_CURL_USER ;
2108
- break ;
2109
-
2110
2101
case CURLOPT_RETURNTRANSFER :
2111
2102
if (zend_is_true (zvalue )) {
2112
2103
ch -> handlers .write -> method = PHP_CURL_RETURN ;
@@ -2716,13 +2707,15 @@ static void curl_free_obj(zend_object *object)
2716
2707
}
2717
2708
2718
2709
smart_str_free (& ch -> handlers .write -> buf );
2719
- zval_ptr_dtor (& ch -> handlers .read -> func_name );
2720
2710
if (ZEND_FCC_INITIALIZED (ch -> handlers .write -> fcc )) {
2721
2711
zend_fcc_dtor (& ch -> handlers .write -> fcc );
2722
2712
}
2723
2713
if (ZEND_FCC_INITIALIZED (ch -> handlers .write_header -> fcc )) {
2724
2714
zend_fcc_dtor (& ch -> handlers .write_header -> fcc );
2725
2715
}
2716
+ if (ZEND_FCC_INITIALIZED (ch -> handlers .read -> fcc )) {
2717
+ zend_fcc_dtor (& ch -> handlers .read -> fcc );
2718
+ }
2726
2719
zval_ptr_dtor (& ch -> handlers .std_err );
2727
2720
if (ch -> header .str ) {
2728
2721
zend_string_release_ex (ch -> header .str , 0 );
0 commit comments