@@ -479,12 +479,16 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
479
479
}
480
480
481
481
if (curl -> handlers .write ) {
482
- zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .write -> func_name );
482
+ if (ZEND_FCC_INITIALIZED (curl -> handlers .write -> fcc )) {
483
+ zend_get_gc_buffer_add_fcc (gc_buffer , & curl -> handlers .write -> fcc );
484
+ }
483
485
zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .write -> stream );
484
486
}
485
487
486
488
if (curl -> handlers .write_header ) {
487
- zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .write_header -> func_name );
489
+ if (ZEND_FCC_INITIALIZED (curl -> handlers .write_header -> fcc )) {
490
+ zend_get_gc_buffer_add_fcc (gc_buffer , & curl -> handlers .write_header -> fcc );
491
+ }
488
492
zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .write_header -> stream );
489
493
}
490
494
@@ -563,51 +567,39 @@ static size_t curl_write_nothing(char *data, size_t size, size_t nmemb, void *ct
563
567
static size_t curl_write (char * data , size_t size , size_t nmemb , void * ctx )
564
568
{
565
569
php_curl * ch = (php_curl * ) ctx ;
566
- php_curl_write * t = ch -> handlers .write ;
570
+ php_curl_write * write_handler = ch -> handlers .write ;
567
571
size_t length = size * nmemb ;
568
572
569
573
#if PHP_CURL_DEBUG
570
574
fprintf (stderr , "curl_write() called\n" );
571
575
fprintf (stderr , "data = %s, size = %d, nmemb = %d, ctx = %x\n" , data , size , nmemb , ctx );
572
576
#endif
573
577
574
- switch (t -> method ) {
578
+ switch (write_handler -> method ) {
575
579
case PHP_CURL_STDOUT :
576
580
PHPWRITE (data , length );
577
581
break ;
578
582
case PHP_CURL_FILE :
579
- return fwrite (data , size , nmemb , t -> fp );
583
+ return fwrite (data , size , nmemb , write_handler -> fp );
580
584
case PHP_CURL_RETURN :
581
585
if (length > 0 ) {
582
- smart_str_appendl (& t -> buf , data , (int ) length );
586
+ smart_str_appendl (& write_handler -> buf , data , (int ) length );
583
587
}
584
588
break ;
585
589
case PHP_CURL_USER : {
586
590
zval argv [2 ];
587
591
zval retval ;
588
- int error ;
589
- zend_fcall_info fci ;
590
592
591
593
GC_ADDREF (& ch -> std );
592
594
ZVAL_OBJ (& argv [0 ], & ch -> std );
593
595
ZVAL_STRINGL (& argv [1 ], data , length );
594
596
595
- fci .size = sizeof (fci );
596
- fci .object = NULL ;
597
- ZVAL_COPY_VALUE (& fci .function_name , & t -> func_name );
598
- fci .retval = & retval ;
599
- fci .param_count = 2 ;
600
- fci .params = argv ;
601
- fci .named_params = NULL ;
602
-
603
- ch -> in_callback = 1 ;
604
- error = zend_call_function (& fci , & t -> fci_cache );
605
- ch -> in_callback = 0 ;
606
- if (error == FAILURE ) {
607
- php_error_docref (NULL , E_WARNING , "Could not call the CURLOPT_WRITEFUNCTION" );
608
- length = -1 ;
609
- } else if (!Z_ISUNDEF (retval )) {
597
+ ch -> in_callback = true;
598
+ zend_call_known_fcc (& write_handler -> fcc , & retval , /* param_count */ 2 , argv , /* named_params */ NULL );
599
+ ch -> in_callback = false;
600
+ if (!Z_ISUNDEF (retval )) {
610
601
_php_curl_verify_handlers (ch , /* reporterror */ true);
602
+ /* TODO Check callback returns an int or something castable to int */
611
603
length = zval_get_long (& retval );
612
604
}
613
605
@@ -838,10 +830,10 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
838
830
static size_t curl_write_header (char * data , size_t size , size_t nmemb , void * ctx )
839
831
{
840
832
php_curl * ch = (php_curl * ) ctx ;
841
- php_curl_write * t = ch -> handlers .write_header ;
833
+ php_curl_write * write_handler = ch -> handlers .write_header ;
842
834
size_t length = size * nmemb ;
843
835
844
- switch (t -> method ) {
836
+ switch (write_handler -> method ) {
845
837
case PHP_CURL_STDOUT :
846
838
/* Handle special case write when we're returning the entire transfer
847
839
*/
@@ -852,32 +844,20 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx
852
844
}
853
845
break ;
854
846
case PHP_CURL_FILE :
855
- return fwrite (data , size , nmemb , t -> fp );
847
+ return fwrite (data , size , nmemb , write_handler -> fp );
856
848
case PHP_CURL_USER : {
857
849
zval argv [2 ];
858
850
zval retval ;
859
- zend_result error ;
860
- zend_fcall_info fci ;
861
851
862
852
GC_ADDREF (& ch -> std );
863
853
ZVAL_OBJ (& argv [0 ], & ch -> std );
864
854
ZVAL_STRINGL (& argv [1 ], data , length );
865
855
866
- fci .size = sizeof (fci );
867
- ZVAL_COPY_VALUE (& fci .function_name , & t -> func_name );
868
- fci .object = NULL ;
869
- fci .retval = & retval ;
870
- fci .param_count = 2 ;
871
- fci .params = argv ;
872
- fci .named_params = NULL ;
873
-
874
- ch -> in_callback = 1 ;
875
- error = zend_call_function (& fci , & t -> fci_cache );
876
- ch -> in_callback = 0 ;
877
- if (error == FAILURE ) {
878
- php_error_docref (NULL , E_WARNING , "Could not call the CURLOPT_HEADERFUNCTION" );
879
- length = -1 ;
880
- } else if (!Z_ISUNDEF (retval )) {
856
+ ch -> in_callback = true;
857
+ zend_call_known_fcc (& write_handler -> fcc , & retval , /* param_count */ 2 , argv , /* named_params */ NULL );
858
+ ch -> in_callback = false;
859
+ if (!Z_ISUNDEF (retval )) {
860
+ // TODO: Check for valid int type for return value
881
861
_php_curl_verify_handlers (ch , /* reporterror */ true);
882
862
length = zval_get_long (& retval );
883
863
}
@@ -1232,15 +1212,17 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
1232
1212
ch -> handlers .read -> fp = source -> handlers .read -> fp ;
1233
1213
ch -> handlers .read -> res = source -> handlers .read -> res ;
1234
1214
1235
- if (!Z_ISUNDEF (source -> handlers .write -> func_name )) {
1236
- ZVAL_COPY (& ch -> handlers .write -> func_name , & source -> handlers .write -> func_name );
1237
- }
1238
1215
if (!Z_ISUNDEF (source -> handlers .read -> func_name )) {
1239
1216
ZVAL_COPY (& ch -> handlers .read -> func_name , & source -> handlers .read -> func_name );
1240
1217
}
1241
- if (!Z_ISUNDEF (source -> handlers .write_header -> func_name )) {
1242
- ZVAL_COPY (& ch -> handlers .write_header -> func_name , & source -> handlers .write_header -> func_name );
1218
+ if (ZEND_FCC_INITIALIZED (source -> handlers .write -> fcc )) {
1219
+ zend_fcc_dup (& source -> handlers .write -> fcc , & source -> handlers .write -> fcc );
1220
+ }
1221
+ if (ZEND_FCC_INITIALIZED (source -> handlers .write_header -> fcc )) {
1222
+ zend_fcc_dup (& source -> handlers .write_header -> fcc , & source -> handlers .write_header -> fcc );
1243
1223
}
1224
+ php_curl_copy_fcc_with_option (ch , CURLOPT_XFERINFODATA , & ch -> handlers .xferinfo , & source -> handlers .xferinfo );
1225
+ php_curl_copy_fcc_with_option (ch , CURLOPT_XFERINFODATA , & ch -> handlers .xferinfo , & source -> handlers .xferinfo );
1244
1226
1245
1227
curl_easy_setopt (ch -> cp , CURLOPT_ERRORBUFFER , ch -> err .str );
1246
1228
curl_easy_setopt (ch -> cp , CURLOPT_FILE , (void * ) ch );
@@ -2087,15 +2069,6 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
2087
2069
error = curl_easy_setopt (ch -> cp , option , lval );
2088
2070
break ;
2089
2071
2090
- case CURLOPT_HEADERFUNCTION :
2091
- if (!Z_ISUNDEF (ch -> handlers .write_header -> func_name )) {
2092
- zval_ptr_dtor (& ch -> handlers .write_header -> func_name );
2093
- ch -> handlers .write_header -> fci_cache = empty_fcall_info_cache ;
2094
- }
2095
- ZVAL_COPY (& ch -> handlers .write_header -> func_name , zvalue );
2096
- ch -> handlers .write_header -> method = PHP_CURL_USER ;
2097
- break ;
2098
-
2099
2072
case CURLOPT_POSTFIELDS :
2100
2073
if (Z_TYPE_P (zvalue ) == IS_ARRAY ) {
2101
2074
if (zend_hash_num_elements (HASH_OF (zvalue )) == 0 ) {
@@ -2116,6 +2089,28 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
2116
2089
}
2117
2090
break ;
2118
2091
2092
+ case CURLOPT_WRITEFUNCTION : {
2093
+ /* Check value is actually a callable and set it */
2094
+ const char option_name [] = "CURLOPT_WRITEFUNCTION" ;
2095
+ bool result = php_curl_set_callable_handler (& ch -> handlers .write -> fcc , zvalue , is_array_config , option_name );
2096
+ if (!result ) {
2097
+ return FAILURE ;
2098
+ }
2099
+ ch -> handlers .write -> method = PHP_CURL_USER ;
2100
+ break ;
2101
+ }
2102
+
2103
+ case CURLOPT_HEADERFUNCTION : {
2104
+ /* Check value is actually a callable and set it */
2105
+ const char option_name [] = "CURLOPT_HEADERFUNCTION" ;
2106
+ bool result = php_curl_set_callable_handler (& ch -> handlers .write_header -> fcc , zvalue , is_array_config , option_name );
2107
+ if (!result ) {
2108
+ return FAILURE ;
2109
+ }
2110
+ ch -> handlers .write_header -> method = PHP_CURL_USER ;
2111
+ break ;
2112
+ }
2113
+
2119
2114
case CURLOPT_PROGRESSFUNCTION : {
2120
2115
/* Check value is actually a callable and set it */
2121
2116
const char option_name [] = "CURLOPT_PROGRESSFUNCTION" ;
@@ -2183,15 +2178,6 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
2183
2178
}
2184
2179
break ;
2185
2180
2186
- case CURLOPT_WRITEFUNCTION :
2187
- if (!Z_ISUNDEF (ch -> handlers .write -> func_name )) {
2188
- zval_ptr_dtor (& ch -> handlers .write -> func_name );
2189
- ch -> handlers .write -> fci_cache = empty_fcall_info_cache ;
2190
- }
2191
- ZVAL_COPY (& ch -> handlers .write -> func_name , zvalue );
2192
- ch -> handlers .write -> method = PHP_CURL_USER ;
2193
- break ;
2194
-
2195
2181
/* Curl off_t options */
2196
2182
case CURLOPT_MAX_RECV_SPEED_LARGE :
2197
2183
case CURLOPT_MAX_SEND_SPEED_LARGE :
@@ -2793,9 +2779,13 @@ static void curl_free_obj(zend_object *object)
2793
2779
}
2794
2780
2795
2781
smart_str_free (& ch -> handlers .write -> buf );
2796
- zval_ptr_dtor (& ch -> handlers .write -> func_name );
2797
2782
zval_ptr_dtor (& ch -> handlers .read -> func_name );
2798
- zval_ptr_dtor (& ch -> handlers .write_header -> func_name );
2783
+ if (ZEND_FCC_INITIALIZED (ch -> handlers .write -> fcc )) {
2784
+ zend_fcc_dtor (& ch -> handlers .write -> fcc );
2785
+ }
2786
+ if (ZEND_FCC_INITIALIZED (ch -> handlers .write_header -> fcc )) {
2787
+ zend_fcc_dtor (& ch -> handlers .write_header -> fcc );
2788
+ }
2799
2789
zval_ptr_dtor (& ch -> handlers .std_err );
2800
2790
if (ch -> header .str ) {
2801
2791
zend_string_release_ex (ch -> header .str , 0 );
0 commit comments