Skip to content

Commit

Permalink
ext/pdo: Convert def_stmt_ctor_args field from zval to Hashtable pointer
Browse files Browse the repository at this point in the history
  • Loading branch information
Girgias committed Jan 9, 2025
1 parent 8ec0ed1 commit 29bf5d3
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 35 deletions.
64 changes: 30 additions & 34 deletions ext/pdo/pdo_dbh.c
Original file line number Diff line number Diff line change
Expand Up @@ -540,15 +540,12 @@ PHP_METHOD(PDO, connect)
}
/* }}} */

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)) {
if (ctor_args && dbstmt_ce->constructor == NULL) {
/* This implies an error within PDO if this does not hold */
ZEND_ASSERT(Z_TYPE_P(ctor_args) == IS_ARRAY);
if (!dbstmt_ce->constructor) {
zend_throw_error(NULL, "User-supplied statement does not accept constructor arguments");
return NULL;
}
zend_throw_error(NULL, "User-supplied statement does not accept constructor arguments");
return NULL;
}

if (UNEXPECTED(object_init_ex(object, dbstmt_ce) != SUCCESS)) {
Expand Down Expand Up @@ -581,10 +578,11 @@ PHP_METHOD(PDO, prepare)
{
pdo_stmt_t *stmt;
zend_string *statement;
zval *options = NULL, *value, *item, ctor_args;
zval *options = NULL, *value, *item;
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;
HashTable *ctor_args = NULL;

ZEND_PARSE_PARAMETERS_START(1, 2)
Z_PARAM_STR(statement)
Expand Down Expand Up @@ -631,16 +629,14 @@ PHP_METHOD(PDO, prepare)
zend_zval_value_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);
Expand All @@ -655,11 +651,7 @@ PHP_METHOD(PDO, prepare)
ZVAL_UNDEF(&stmt->lazy_object_ref);

if (dbh->methods->preparer(dbh, statement, stmt, options)) {
if (Z_TYPE(ctor_args) == IS_ARRAY) {
pdo_stmt_construct(stmt, return_value, dbstmt_ce, Z_ARRVAL(ctor_args));
} else {
pdo_stmt_construct(stmt, return_value, dbstmt_ce, /* ctor_args */ NULL);
}
pdo_stmt_construct(stmt, return_value, dbstmt_ce, ctor_args);
return;
}

Expand Down Expand Up @@ -923,17 +915,19 @@ 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 != NULL) {
zend_array_release(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) {
zend_type_error("PDO::ATTR_STATEMENT_CLASS constructor_args must be of type ?array, %s given",
zend_zval_value_name(value));
return false;
}
ZVAL_COPY(&dbh->def_stmt_ctor_args, item);
dbh->def_stmt_ctor_args = Z_ARRVAL_P(item);
/* Increase refcount */
GC_TRY_ADDREF(dbh->def_stmt_ctor_args);
}
return true;
}
Expand Down Expand Up @@ -1012,9 +1006,10 @@ 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 != NULL) {
/* Increase refcount */
GC_TRY_ADDREF(dbh->def_stmt_ctor_args);
add_next_index_array(return_value, dbh->def_stmt_ctor_args);
}
return;

Expand Down Expand Up @@ -1204,7 +1199,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);
Expand Down Expand Up @@ -1233,11 +1228,7 @@ PHP_METHOD(PDO, query)
stmt->executed = 1;
}
if (ret) {
if (Z_TYPE(dbh->def_stmt_ctor_args) == IS_ARRAY) {
pdo_stmt_construct(stmt, return_value, dbh->def_stmt_ce, Z_ARRVAL(dbh->def_stmt_ctor_args));
} else {
pdo_stmt_construct(stmt, return_value, dbh->def_stmt_ce, /* ctor_args */ NULL);
}
pdo_stmt_construct(stmt, return_value, dbh->def_stmt_ce, dbh->def_stmt_ctor_args);
return;
}
}
Expand Down Expand Up @@ -1432,7 +1423,10 @@ 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 != NULL) {
zend_get_gc_buffer_add_ht(gc_buffer, dbh->def_stmt_ctor_args);
dbh->def_stmt_ctor_args = NULL;
}
if (dbh->methods && dbh->methods->get_gc) {
dbh->methods->get_gc(dbh, gc_buffer);
}
Expand Down Expand Up @@ -1495,8 +1489,9 @@ 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);
if (dbh->def_stmt_ctor_args != NULL) {
zend_array_release(dbh->def_stmt_ctor_args);
dbh->def_stmt_ctor_args = NULL;
}

for (i = 0; i < PDO_DBH_DRIVER_METHOD_KIND__MAX; i++) {
Expand Down Expand Up @@ -1541,6 +1536,7 @@ zend_object *pdo_dbh_new(zend_class_entry *ce)
zend_std_get_properties_ex(&dbh->std);
dbh->inner = ecalloc(1, sizeof(pdo_dbh_t));
dbh->inner->def_stmt_ce = pdo_dbstmt_ce;
dbh->inner->def_stmt_ctor_args = NULL;

return &dbh->std;
}
Expand Down
2 changes: 1 addition & 1 deletion ext/pdo/php_pdo_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,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.
Expand Down

0 comments on commit 29bf5d3

Please sign in to comment.