Skip to content

Commit b82bc76

Browse files
committed
ext/pdo: Convert def_stmt_ctor_args field from zval to Hashtable pointer
1 parent 0baf03d commit b82bc76

File tree

2 files changed

+31
-35
lines changed

2 files changed

+31
-35
lines changed

ext/pdo/pdo_dbh.c

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

ext/pdo/php_pdo_driver.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ struct _pdo_dbh_t {
495495

496496
zend_class_entry *def_stmt_ce;
497497

498-
zval def_stmt_ctor_args;
498+
HashTable *def_stmt_ctor_args;
499499

500500
/* when calling PDO::query(), we need to keep the error
501501
* context from the statement around until we next clear it.

0 commit comments

Comments
 (0)