@@ -372,51 +372,36 @@ static int _php_server_push_callback(CURL *parent_ch, CURL *easy, size_t num_hea
372
372
php_curl * parent ;
373
373
php_curlm * mh = (php_curlm * )userp ;
374
374
size_t rval = CURL_PUSH_DENY ;
375
- php_curl_callback * t = mh -> handlers .server_push ;
376
375
zval * pz_parent_ch = NULL ;
377
376
zval pz_ch ;
378
377
zval headers ;
379
378
zval retval ;
380
- char * header ;
381
- zend_result error ;
382
- zend_fcall_info fci = empty_fcall_info ;
383
379
384
380
pz_parent_ch = _php_curl_multi_find_easy_handle (mh , parent_ch );
385
381
if (pz_parent_ch == NULL ) {
386
382
return rval ;
387
383
}
388
384
389
- if (UNEXPECTED (zend_fcall_info_init (& t -> func_name , 0 , & fci , & t -> fci_cache , NULL , NULL ) == FAILURE )) {
390
- php_error_docref (NULL , E_WARNING , "Cannot call the CURLMOPT_PUSHFUNCTION" );
391
- return rval ;
392
- }
393
-
394
385
parent = Z_CURL_P (pz_parent_ch );
395
386
396
387
ch = init_curl_handle_into_zval (& pz_ch );
397
388
ch -> cp = easy ;
398
389
_php_setup_easy_copy_handlers (ch , parent );
399
390
400
- size_t i ;
401
391
array_init (& headers );
402
- for (i = 0 ; i < num_headers ; i ++ ) {
392
+ for (size_t i = 0 ; i < num_headers ; i ++ ) {
393
+ char * header ;
403
394
header = curl_pushheader_bynum (push_headers , i );
404
395
add_next_index_string (& headers , header );
405
396
}
406
397
407
398
ZEND_ASSERT (pz_parent_ch );
408
399
zval call_args [3 ] = {* pz_parent_ch , pz_ch , headers };
409
400
410
- fci .param_count = 3 ;
411
- fci .params = call_args ;
412
- fci .retval = & retval ;
413
-
414
- error = zend_call_function (& fci , & t -> fci_cache );
401
+ zend_call_known_fcc (& mh -> handlers .server_push , & retval , /* param_count */ 3 , call_args , /* named_params */ NULL );
415
402
zval_ptr_dtor_nogc (& headers );
416
403
417
- if (error == FAILURE ) {
418
- php_error_docref (NULL , E_WARNING , "Cannot call the CURLMOPT_PUSHFUNCTION" );
419
- } else if (!Z_ISUNDEF (retval )) {
404
+ if (!Z_ISUNDEF (retval )) {
420
405
if (CURL_PUSH_DENY != zval_get_long (& retval )) {
421
406
rval = CURL_PUSH_OK ;
422
407
zend_llist_add_element (& mh -> easyh , & pz_ch );
@@ -458,21 +443,29 @@ static bool _php_curl_multi_setopt(php_curlm *mh, zend_long option, zval *zvalue
458
443
error = curl_multi_setopt (mh -> multi , option , lval );
459
444
break ;
460
445
}
461
- case CURLMOPT_PUSHFUNCTION :
462
- if (mh -> handlers .server_push == NULL ) {
463
- mh -> handlers .server_push = ecalloc (1 , sizeof (php_curl_callback ));
464
- } else if (!Z_ISUNDEF (mh -> handlers .server_push -> func_name )) {
465
- zval_ptr_dtor (& mh -> handlers .server_push -> func_name );
466
- mh -> handlers .server_push -> fci_cache = empty_fcall_info_cache ;
446
+ case CURLMOPT_PUSHFUNCTION : {
447
+ /* See php_curl_set_callable_handler */
448
+ if (ZEND_FCC_INITIALIZED (mh -> handlers .server_push )) {
449
+ zend_fcc_dtor (& mh -> handlers .server_push );
467
450
}
468
451
469
- ZVAL_COPY (& mh -> handlers .server_push -> func_name , zvalue );
452
+ char * error_str = NULL ;
453
+ if (UNEXPECTED (!zend_is_callable_ex (zvalue , /* object */ NULL , /* check_flags */ 0 , /* callable_name */ NULL , & mh -> handlers .server_push , /* error */ & error_str ))) {
454
+ if (!EG (exception )) {
455
+ zend_argument_type_error (2 , "must be a valid callback for option CURLMOPT_PUSHFUNCTION, %s" , error );
456
+ }
457
+ efree (error_str );
458
+ return false;
459
+ }
460
+ zend_fcc_addref (& mh -> handlers .server_push );
461
+
470
462
error = curl_multi_setopt (mh -> multi , CURLMOPT_PUSHFUNCTION , _php_server_push_callback );
471
463
if (error != CURLM_OK ) {
472
464
return false;
473
465
}
474
466
error = curl_multi_setopt (mh -> multi , CURLMOPT_PUSHDATA , mh );
475
467
break ;
468
+ }
476
469
default :
477
470
zend_argument_value_error (2 , "is not a valid cURL multi option" );
478
471
error = CURLM_UNKNOWN_OPTION ;
@@ -548,9 +541,9 @@ static void curl_multi_free_obj(zend_object *object)
548
541
549
542
curl_multi_cleanup (mh -> multi );
550
543
zend_llist_clean (& mh -> easyh );
551
- if ( mh -> handlers . server_push ) {
552
- zval_ptr_dtor ( & mh -> handlers .server_push -> func_name );
553
- efree ( mh -> handlers .server_push );
544
+
545
+ if ( ZEND_FCC_INITIALIZED ( mh -> handlers .server_push )) {
546
+ zend_fcc_dtor ( & mh -> handlers .server_push );
554
547
}
555
548
556
549
zend_object_std_dtor (& mh -> std );
@@ -562,8 +555,8 @@ static HashTable *curl_multi_get_gc(zend_object *object, zval **table, int *n)
562
555
563
556
zend_get_gc_buffer * gc_buffer = zend_get_gc_buffer_create ();
564
557
565
- if (curl_multi -> handlers .server_push ) {
566
- zend_get_gc_buffer_add_zval (gc_buffer , & curl_multi -> handlers .server_push -> func_name );
558
+ if (ZEND_FCC_INITIALIZED ( curl_multi -> handlers .server_push ) ) {
559
+ zend_get_gc_buffer_add_fcc (gc_buffer , & curl_multi -> handlers .server_push );
567
560
}
568
561
569
562
zend_llist_position pos ;
0 commit comments