Skip to content

Commit bd83f86

Browse files
committed
ext/pdo: Refactor FETCH_FUNCTION mode
Most of the fields on the struct are useless or can be handled differently
1 parent 576f5fa commit bd83f86

File tree

2 files changed

+15
-47
lines changed

2 files changed

+15
-47
lines changed

ext/pdo/pdo_stmt.c

Lines changed: 14 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -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;

ext/pdo/php_pdo_driver.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -619,12 +619,9 @@ struct _pdo_stmt_t {
619619
zend_class_entry *ce;
620620
} cls;
621621
struct {
622-
zval fetch_args; /* freed */
622+
zval dummy; /* This exists due to alignment reasons with fetch.into and fetch.cls.ctor_args */
623623
zend_fcall_info fci;
624624
zend_fcall_info_cache fcc;
625-
zval object;
626-
zval function;
627-
zval *values; /* freed */
628625
} func;
629626
zval into;
630627
} fetch;

0 commit comments

Comments
 (0)