@@ -542,15 +542,12 @@ PHP_METHOD(PDO, connect)
542542}
543543/* }}} */
544544
545- static zval * pdo_stmt_instantiate (pdo_dbh_t * dbh , zval * object , zend_class_entry * dbstmt_ce , zval * ctor_args ) /* {{{ */
545+ static zval * pdo_stmt_instantiate (pdo_dbh_t * dbh , zval * object , zend_class_entry * dbstmt_ce , const HashTable * ctor_args ) /* {{{ */
546546{
547- if (! Z_ISUNDEF_P ( ctor_args ) ) {
547+ if (ctor_args && dbstmt_ce -> constructor == NULL ) {
548548 /* This implies an error within PDO if this does not hold */
549- ZEND_ASSERT (Z_TYPE_P (ctor_args ) == IS_ARRAY );
550- if (!dbstmt_ce -> constructor ) {
551- zend_throw_error (NULL , "User-supplied statement does not accept constructor arguments" );
552- return NULL ;
553- }
549+ zend_throw_error (NULL , "User-supplied statement does not accept constructor arguments" );
550+ return NULL ;
554551 }
555552
556553 if (UNEXPECTED (object_init_ex (object , dbstmt_ce ) != SUCCESS )) {
@@ -583,10 +580,11 @@ PHP_METHOD(PDO, prepare)
583580{
584581 pdo_stmt_t * stmt ;
585582 zend_string * statement ;
586- zval * options = NULL , * value , * item , ctor_args ;
583+ zval * options = NULL , * value , * item ;
587584 zend_class_entry * dbstmt_ce , * pce ;
588585 pdo_dbh_object_t * dbh_obj = Z_PDO_OBJECT_P (ZEND_THIS );
589586 pdo_dbh_t * dbh = dbh_obj -> inner ;
587+ HashTable * ctor_args = NULL ;
590588
591589 ZEND_PARSE_PARAMETERS_START (1 , 2 )
592590 Z_PARAM_STR (statement )
@@ -633,16 +631,14 @@ PHP_METHOD(PDO, prepare)
633631 zend_zval_value_name (value ));
634632 RETURN_THROWS ();
635633 }
636- ZVAL_COPY_VALUE (& ctor_args , item );
637- } else {
638- ZVAL_UNDEF (& ctor_args );
634+ ctor_args = Z_ARRVAL_P (item );
639635 }
640636 } else {
641637 dbstmt_ce = dbh -> def_stmt_ce ;
642- ZVAL_COPY_VALUE ( & ctor_args , & dbh -> def_stmt_ctor_args ) ;
638+ ctor_args = dbh -> def_stmt_ctor_args ;
643639 }
644640
645- if (!pdo_stmt_instantiate (dbh , return_value , dbstmt_ce , & ctor_args )) {
641+ if (!pdo_stmt_instantiate (dbh , return_value , dbstmt_ce , ctor_args )) {
646642 RETURN_THROWS ();
647643 }
648644 stmt = Z_PDO_STMT_P (return_value );
@@ -656,11 +652,7 @@ PHP_METHOD(PDO, prepare)
656652 stmt -> database_object_handle = & dbh_obj -> std ;
657653
658654 if (dbh -> methods -> preparer (dbh , statement , stmt , options )) {
659- if (Z_TYPE (ctor_args ) == IS_ARRAY ) {
660- pdo_stmt_construct (stmt , return_value , dbstmt_ce , Z_ARRVAL (ctor_args ));
661- } else {
662- pdo_stmt_construct (stmt , return_value , dbstmt_ce , /* ctor_args */ NULL );
663- }
655+ pdo_stmt_construct (stmt , return_value , dbstmt_ce , ctor_args );
664656 return ;
665657 }
666658
@@ -924,17 +916,19 @@ static bool pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value, u
924916 return false;
925917 }
926918 dbh -> def_stmt_ce = pce ;
927- if (! Z_ISUNDEF ( dbh -> def_stmt_ctor_args ) ) {
928- zval_ptr_dtor ( & dbh -> def_stmt_ctor_args );
929- ZVAL_UNDEF ( & dbh -> def_stmt_ctor_args ) ;
919+ if (dbh -> def_stmt_ctor_args != NULL ) {
920+ zend_array_release ( dbh -> def_stmt_ctor_args );
921+ dbh -> def_stmt_ctor_args = NULL ;
930922 }
931923 if ((item = zend_hash_index_find (Z_ARRVAL_P (value ), 1 )) != NULL ) {
932924 if (Z_TYPE_P (item ) != IS_ARRAY ) {
933925 zend_argument_type_error (value_arg_num , "PDO::ATTR_STATEMENT_CLASS constructor_args must be of type ?array, %s given" ,
934926 zend_zval_value_name (value ));
935927 return false;
936928 }
937- ZVAL_COPY (& dbh -> def_stmt_ctor_args , item );
929+ dbh -> def_stmt_ctor_args = Z_ARRVAL_P (item );
930+ /* Increase refcount */
931+ GC_TRY_ADDREF (dbh -> def_stmt_ctor_args );
938932 }
939933 return true;
940934 }
@@ -1013,9 +1007,10 @@ PHP_METHOD(PDO, getAttribute)
10131007 case PDO_ATTR_STATEMENT_CLASS :
10141008 array_init (return_value );
10151009 add_next_index_str (return_value , zend_string_copy (dbh -> def_stmt_ce -> name ));
1016- if (!Z_ISUNDEF (dbh -> def_stmt_ctor_args )) {
1017- Z_TRY_ADDREF (dbh -> def_stmt_ctor_args );
1018- add_next_index_zval (return_value , & dbh -> def_stmt_ctor_args );
1010+ if (dbh -> def_stmt_ctor_args != NULL ) {
1011+ /* Increase refcount */
1012+ GC_TRY_ADDREF (dbh -> def_stmt_ctor_args );
1013+ add_next_index_array (return_value , dbh -> def_stmt_ctor_args );
10191014 }
10201015 return ;
10211016
@@ -1205,7 +1200,7 @@ PHP_METHOD(PDO, query)
12051200
12061201 PDO_DBH_CLEAR_ERR ();
12071202
1208- if (!pdo_stmt_instantiate (dbh , return_value , dbh -> def_stmt_ce , & dbh -> def_stmt_ctor_args )) {
1203+ if (!pdo_stmt_instantiate (dbh , return_value , dbh -> def_stmt_ce , dbh -> def_stmt_ctor_args )) {
12091204 RETURN_THROWS ();
12101205 }
12111206 stmt = Z_PDO_STMT_P (return_value );
@@ -1233,11 +1228,7 @@ PHP_METHOD(PDO, query)
12331228 stmt -> executed = 1 ;
12341229 }
12351230 if (ret ) {
1236- if (Z_TYPE (dbh -> def_stmt_ctor_args ) == IS_ARRAY ) {
1237- pdo_stmt_construct (stmt , return_value , dbh -> def_stmt_ce , Z_ARRVAL (dbh -> def_stmt_ctor_args ));
1238- } else {
1239- pdo_stmt_construct (stmt , return_value , dbh -> def_stmt_ce , /* ctor_args */ NULL );
1240- }
1231+ pdo_stmt_construct (stmt , return_value , dbh -> def_stmt_ce , dbh -> def_stmt_ctor_args );
12411232 return ;
12421233 }
12431234 }
@@ -1432,7 +1423,10 @@ static HashTable *dbh_get_gc(zend_object *object, zval **gc_data, int *gc_count)
14321423{
14331424 pdo_dbh_t * dbh = php_pdo_dbh_fetch_inner (object );
14341425 zend_get_gc_buffer * gc_buffer = zend_get_gc_buffer_create ();
1435- zend_get_gc_buffer_add_zval (gc_buffer , & dbh -> def_stmt_ctor_args );
1426+ if (dbh -> def_stmt_ctor_args != NULL ) {
1427+ zend_get_gc_buffer_add_ht (gc_buffer , dbh -> def_stmt_ctor_args );
1428+ dbh -> def_stmt_ctor_args = NULL ;
1429+ }
14361430 if (dbh -> methods && dbh -> methods -> get_gc ) {
14371431 dbh -> methods -> get_gc (dbh , gc_buffer );
14381432 }
@@ -1496,8 +1490,9 @@ static void dbh_free(pdo_dbh_t *dbh, bool free_persistent)
14961490 pefree ((char * )dbh -> persistent_id , dbh -> is_persistent );
14971491 }
14981492
1499- if (!Z_ISUNDEF (dbh -> def_stmt_ctor_args )) {
1500- zval_ptr_dtor (& dbh -> def_stmt_ctor_args );
1493+ if (dbh -> def_stmt_ctor_args != NULL ) {
1494+ zend_array_release (dbh -> def_stmt_ctor_args );
1495+ dbh -> def_stmt_ctor_args = NULL ;
15011496 }
15021497
15031498 for (i = 0 ; i < PDO_DBH_DRIVER_METHOD_KIND__MAX ; i ++ ) {
@@ -1542,6 +1537,7 @@ zend_object *pdo_dbh_new(zend_class_entry *ce)
15421537 zend_std_get_properties_ex (& dbh -> std );
15431538 dbh -> inner = ecalloc (1 , sizeof (pdo_dbh_t ));
15441539 dbh -> inner -> def_stmt_ce = pdo_dbstmt_ce ;
1540+ dbh -> inner -> def_stmt_ctor_args = NULL ;
15451541
15461542 return & dbh -> std ;
15471543}
0 commit comments