diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index 47c9072da56e0..3cd86e4443dd8 100644 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -434,11 +434,9 @@ PHP_METHOD(PDO, __construct) } /* }}} */ -static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry *dbstmt_ce, zval *ctor_args) /* {{{ */ +static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry *dbstmt_ce, const HashTable *ctor_args) /* {{{ */ { - if (!Z_ISUNDEF_P(ctor_args)) { - /* This implies an error within PDO if this does not hold */ - ZEND_ASSERT(Z_TYPE_P(ctor_args) == IS_ARRAY); + if (ctor_args) { if (!dbstmt_ce->constructor) { zend_throw_error(NULL, "User-supplied statement does not accept constructor arguments"); return NULL; @@ -455,7 +453,7 @@ static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry return object; } /* }}} */ -static void pdo_stmt_construct(zend_execute_data *execute_data, pdo_stmt_t *stmt, zval *object, zend_class_entry *dbstmt_ce, zval *ctor_args) /* {{{ */ +static void pdo_stmt_construct(zend_execute_data *execute_data, pdo_stmt_t *stmt, zval *object, zend_class_entry *dbstmt_ce, /* const */ HashTable *ctor_args) /* {{{ */ { zval query_string; zend_string *key; @@ -466,29 +464,7 @@ static void pdo_stmt_construct(zend_execute_data *execute_data, pdo_stmt_t *stmt zend_string_release_ex(key, 0); if (dbstmt_ce->constructor) { - zend_fcall_info fci; - zend_fcall_info_cache fcc; - zval retval; - - fci.size = sizeof(zend_fcall_info); - ZVAL_UNDEF(&fci.function_name); - fci.object = Z_OBJ_P(object); - fci.retval = &retval; - fci.param_count = 0; - fci.params = NULL; - fci.named_params = NULL; - - zend_fcall_info_args(&fci, ctor_args); - - fcc.function_handler = dbstmt_ce->constructor; - fcc.called_scope = Z_OBJCE_P(object); - fcc.object = Z_OBJ_P(object); - - if (zend_call_function(&fci, &fcc) != FAILURE) { - zval_ptr_dtor(&retval); - } - - zend_fcall_info_args_clear(&fci, 1); + zend_call_known_function(dbstmt_ce->constructor, Z_OBJ_P(object), Z_OBJCE_P(object), NULL, 0, NULL, ctor_args); } } /* }}} */ @@ -498,7 +474,8 @@ PHP_METHOD(PDO, prepare) { pdo_stmt_t *stmt; zend_string *statement; - zval *options = NULL, *value, *item, ctor_args; + zval *options = NULL, *value, *item; + HashTable *ctor_args = NULL; zend_class_entry *dbstmt_ce, *pce; pdo_dbh_object_t *dbh_obj = Z_PDO_OBJECT_P(ZEND_THIS); pdo_dbh_t *dbh = dbh_obj->inner; @@ -548,16 +525,14 @@ PHP_METHOD(PDO, prepare) zend_zval_type_name(value)); RETURN_THROWS(); } - ZVAL_COPY_VALUE(&ctor_args, item); - } else { - ZVAL_UNDEF(&ctor_args); + ctor_args = Z_ARRVAL_P(item); } } else { dbstmt_ce = dbh->def_stmt_ce; - ZVAL_COPY_VALUE(&ctor_args, &dbh->def_stmt_ctor_args); + ctor_args = dbh->def_stmt_ctor_args; } - if (!pdo_stmt_instantiate(dbh, return_value, dbstmt_ce, &ctor_args)) { + if (!pdo_stmt_instantiate(dbh, return_value, dbstmt_ce, ctor_args)) { RETURN_THROWS(); } stmt = Z_PDO_STMT_P(return_value); @@ -572,7 +547,7 @@ PHP_METHOD(PDO, prepare) ZVAL_UNDEF(&stmt->lazy_object_ref); if (dbh->methods->preparer(dbh, statement, stmt, options)) { - pdo_stmt_construct(execute_data, stmt, return_value, dbstmt_ce, &ctor_args); + pdo_stmt_construct(execute_data, stmt, return_value, dbstmt_ce, ctor_args); return; } @@ -833,9 +808,9 @@ static bool pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) / return false; } dbh->def_stmt_ce = pce; - if (!Z_ISUNDEF(dbh->def_stmt_ctor_args)) { - zval_ptr_dtor(&dbh->def_stmt_ctor_args); - ZVAL_UNDEF(&dbh->def_stmt_ctor_args); + if (dbh->def_stmt_ctor_args) { + zend_hash_destroy(dbh->def_stmt_ctor_args); + dbh->def_stmt_ctor_args = NULL; } if ((item = zend_hash_index_find(Z_ARRVAL_P(value), 1)) != NULL) { if (Z_TYPE_P(item) != IS_ARRAY) { @@ -843,7 +818,7 @@ static bool pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) / zend_zval_type_name(value)); return false; } - ZVAL_COPY(&dbh->def_stmt_ctor_args, item); + dbh->def_stmt_ctor_args = zend_array_dup(Z_ARRVAL_P(item)); } return true; } @@ -922,9 +897,8 @@ PHP_METHOD(PDO, getAttribute) case PDO_ATTR_STATEMENT_CLASS: array_init(return_value); add_next_index_str(return_value, zend_string_copy(dbh->def_stmt_ce->name)); - if (!Z_ISUNDEF(dbh->def_stmt_ctor_args)) { - Z_TRY_ADDREF(dbh->def_stmt_ctor_args); - add_next_index_zval(return_value, &dbh->def_stmt_ctor_args); + if (dbh->def_stmt_ctor_args) { + add_next_index_array(return_value, zend_array_dup(dbh->def_stmt_ctor_args)); } return; case PDO_ATTR_DEFAULT_FETCH_MODE: @@ -1109,7 +1083,7 @@ PHP_METHOD(PDO, query) PDO_DBH_CLEAR_ERR(); - if (!pdo_stmt_instantiate(dbh, return_value, dbh->def_stmt_ce, &dbh->def_stmt_ctor_args)) { + if (!pdo_stmt_instantiate(dbh, return_value, dbh->def_stmt_ce, dbh->def_stmt_ctor_args)) { RETURN_THROWS(); } stmt = Z_PDO_STMT_P(return_value); @@ -1138,7 +1112,7 @@ PHP_METHOD(PDO, query) stmt->executed = 1; } if (ret) { - pdo_stmt_construct(execute_data, stmt, return_value, dbh->def_stmt_ce, &dbh->def_stmt_ctor_args); + pdo_stmt_construct(execute_data, stmt, return_value, dbh->def_stmt_ce, dbh->def_stmt_ctor_args); return; } } @@ -1326,7 +1300,11 @@ static HashTable *dbh_get_gc(zend_object *object, zval **gc_data, int *gc_count) { pdo_dbh_t *dbh = php_pdo_dbh_fetch_inner(object); zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create(); - zend_get_gc_buffer_add_zval(gc_buffer, &dbh->def_stmt_ctor_args); + if (dbh->def_stmt_ctor_args) { + zval tmp = {0}; + ZVAL_ARR(&tmp, dbh->def_stmt_ctor_args); + zend_get_gc_buffer_add_zval(gc_buffer, &tmp); + } if (dbh->methods && dbh->methods->get_gc) { dbh->methods->get_gc(dbh, gc_buffer); } @@ -1388,9 +1366,7 @@ static void dbh_free(pdo_dbh_t *dbh, bool free_persistent) pefree((char *)dbh->persistent_id, dbh->is_persistent); } - if (!Z_ISUNDEF(dbh->def_stmt_ctor_args)) { - zval_ptr_dtor(&dbh->def_stmt_ctor_args); - } + /* Freeing of constructor arguments is handles via GC */ for (i = 0; i < PDO_DBH_DRIVER_METHOD_KIND__MAX; i++) { if (dbh->cls_methods[i]) { diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h index c832284627750..f68fb6c16ce47 100644 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/php_pdo_driver.h @@ -487,7 +487,7 @@ struct _pdo_dbh_t { zend_class_entry *def_stmt_ce; - zval def_stmt_ctor_args; + HashTable *def_stmt_ctor_args; /* when calling PDO::query(), we need to keep the error * context from the statement around until we next clear it. diff --git a/run-tests.php b/run-tests.php index 18bf1b04925fe..90bc0365b8d09 100755 --- a/run-tests.php +++ b/run-tests.php @@ -857,13 +857,7 @@ function write_information(): void $php_cgi_info = ''; } - if ($phpdbg) { - $phpdbg_info = shell_exec("$phpdbg $pass_options $info_params $no_file_cache -qrr \"$info_file\""); - $php_info_sep = "\n---------------------------------------------------------------------"; - $phpdbg_info = "$php_info_sep\nPHP : $phpdbg $phpdbg_info$php_info_sep"; - } else { - $phpdbg_info = ''; - } + $phpdbg_info = ''; if (function_exists('opcache_invalidate')) { opcache_invalidate($info_file, true);