@@ -643,11 +643,11 @@ static bool do_fetch_class_prepare(pdo_stmt_t *stmt) /* {{{ */
643643}
644644/* }}} */
645645
646- static bool make_callable_ex (pdo_stmt_t * stmt , zval * callable , zend_fcall_info * fci , zend_fcall_info_cache * fcc , int num_args ) /* {{{ */
646+ static bool pdo_stmt_init_fci_fcc_for_function_fetch_mode (pdo_stmt_t * stmt , zval * callable )
647647{
648648 char * is_callable_error = NULL ;
649649
650- if (zend_fcall_info_init (callable , 0 , fci , fcc , NULL , & is_callable_error ) == FAILURE ) {
650+ if (zend_fcall_info_init (callable , 0 , & stmt -> fetch . func . fci , & stmt -> fetch . func . fcc , NULL , & is_callable_error ) == FAILURE ) {
651651 if (is_callable_error ) {
652652 zend_type_error ("%s" , is_callable_error );
653653 efree (is_callable_error );
@@ -656,33 +656,16 @@ static bool make_callable_ex(pdo_stmt_t *stmt, zval *callable, zend_fcall_info *
656656 }
657657 return false;
658658 }
659- if (is_callable_error ) {
660- /* Possible error message */
661- efree (is_callable_error );
662- }
659+ ZEND_ASSERT (is_callable_error == NULL );
663660
664- fci -> param_count = num_args ; /* probably less */
665- fci -> params = safe_emalloc (sizeof (zval ), num_args , 0 );
661+ uint32_t num_args = stmt -> column_count ;
662+ stmt -> fetch .func .fci .param_count = num_args ; /* probably less */
663+ stmt -> fetch .func .fci .params = safe_emalloc (sizeof (zval ), num_args , 0 );
666664
667665 return true;
668666}
669- /* }}} */
670-
671- static bool do_fetch_func_prepare (pdo_stmt_t * stmt ) /* {{{ */
672- {
673- zend_fcall_info * fci = & stmt -> fetch .cls .fci ;
674- zend_fcall_info_cache * fcc = & stmt -> fetch .cls .fcc ;
675-
676- if (!make_callable_ex (stmt , & stmt -> fetch .func .function , fci , fcc , stmt -> column_count )) {
677- return false;
678- } else {
679- stmt -> fetch .func .values = safe_emalloc (sizeof (zval ), stmt -> column_count , 0 );
680- return true;
681- }
682- }
683- /* }}} */
684667
685- static void do_fetch_opt_finish (pdo_stmt_t * stmt , int free_ctor_agrs ) /* {{{ */
668+ static void do_fetch_opt_finish (pdo_stmt_t * stmt , bool free_ctor_agrs ) /* {{{ */
686669{
687670 /* fci.size is used to check if it is valid */
688671 if (stmt -> fetch .cls .fci .size && stmt -> fetch .cls .fci .params ) {
@@ -701,10 +684,6 @@ static void do_fetch_opt_finish(pdo_stmt_t *stmt, int free_ctor_agrs) /* {{{ */
701684 ZVAL_UNDEF (& stmt -> fetch .cls .ctor_args );
702685 stmt -> fetch .cls .fci .param_count = 0 ;
703686 }
704- if (stmt -> fetch .func .values ) {
705- efree (stmt -> fetch .func .values );
706- stmt -> fetch .func .values = NULL ;
707- }
708687}
709688/* }}} */
710689
@@ -894,16 +873,10 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h
894873
895874 case PDO_FETCH_FUNC :
896875 /* TODO: Make this an assertion and ensure this is true higher up? */
897- if (Z_ISUNDEF (stmt -> fetch .func .function )) {
876+ if (! ZEND_FCI_INITIALIZED (stmt -> fetch .func .fci )) {
898877 /* TODO ArgumentCountError? */
899878 pdo_raise_impl_error (stmt -> dbh , stmt , "HY000" , "No fetch function specified" );
900- return 0 ;
901- }
902- if (!stmt -> fetch .func .fci .size ) {
903- if (!do_fetch_func_prepare (stmt ))
904- {
905- return 0 ;
906- }
879+ return false;
907880 }
908881 break ;
909882 EMPTY_SWITCH_DEFAULT_CASE ();
@@ -999,8 +972,7 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h
999972 break ;
1000973
1001974 case PDO_FETCH_FUNC :
1002- ZVAL_COPY_VALUE (& stmt -> fetch .func .values [idx ], & val );
1003- ZVAL_COPY_VALUE (& stmt -> fetch .cls .fci .params [idx ], & stmt -> fetch .func .values [idx ]);
975+ ZVAL_COPY_VALUE (& stmt -> fetch .func .fci .params [idx ], & val );
1004976 break ;
1005977
1006978 default :
@@ -1045,8 +1017,9 @@ static bool do_fetch(pdo_stmt_t *stmt, zval *return_value, enum pdo_fetch_type h
10451017 ZVAL_COPY_VALUE (return_value , & retval );
10461018 }
10471019 }
1048- while (idx -- ) {
1049- zval_ptr_dtor (& stmt -> fetch .func .values [idx ]);
1020+ /* Free FCI parameters that were allocated in the previous loop */
1021+ for (uint32_t param_num = 0 ; param_num < stmt -> fetch .func .fci .param_count ; param_num ++ ) {
1022+ zval_ptr_dtor (& stmt -> fetch .func .fci .params [param_num ]);
10501023 }
10511024 break ;
10521025
@@ -1295,9 +1268,7 @@ PHP_METHOD(PDOStatement, fetchAll)
12951268 zend_argument_type_error (2 , "must be a callable, null given" );
12961269 RETURN_THROWS ();
12971270 }
1298- /* TODO Check it is a callable? */
1299- ZVAL_COPY_VALUE (& stmt -> fetch .func .function , arg2 );
1300- if (do_fetch_func_prepare (stmt ) == false) {
1271+ if (pdo_stmt_init_fci_fcc_for_function_fetch_mode (stmt , arg2 ) == false) {
13011272 RETURN_THROWS ();
13021273 }
13031274 break ;
0 commit comments