Skip to content

Commit c2ab1a6

Browse files
committed
Revert ZPP to use variadics
1 parent b5b5336 commit c2ab1a6

File tree

4 files changed

+66
-45
lines changed

4 files changed

+66
-45
lines changed

ext/pdo/pdo_dbh.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,13 +1050,13 @@ PHP_METHOD(PDO, query)
10501050
size_t statement_len;
10511051
zend_long fetch_mode;
10521052
zend_bool fetch_mode_is_null = 1;
1053-
zval *arg1 = NULL;
1054-
HashTable *constructor_args = NULL;
1053+
zval *args = NULL;
1054+
uint32_t num_args = 0;
10551055
pdo_dbh_object_t *dbh_obj = Z_PDO_OBJECT_P(ZEND_THIS);
10561056
pdo_dbh_t *dbh = dbh_obj->inner;
10571057

1058-
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "s|l!z!h!", &statement, &statement_len,
1059-
&fetch_mode, &fetch_mode_is_null, &arg1, &constructor_args)) {
1058+
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "s|l!*", &statement, &statement_len,
1059+
&fetch_mode, &fetch_mode_is_null, &args, &num_args)) {
10601060
RETURN_THROWS();
10611061
}
10621062

@@ -1092,8 +1092,7 @@ PHP_METHOD(PDO, query)
10921092

10931093
if (dbh->methods->preparer(dbh, statement, statement_len, stmt, NULL)) {
10941094
PDO_STMT_CLEAR_ERR();
1095-
if (fetch_mode_is_null || pdo_stmt_setup_fetch_mode(stmt, ZEND_NUM_ARGS(),
1096-
fetch_mode, 2, arg1, 3, constructor_args, 4)) {
1095+
if (fetch_mode_is_null || pdo_stmt_setup_fetch_mode(stmt, fetch_mode, 2, args, num_args)) {
10971096
/* now execute the statement */
10981097
PDO_STMT_CLEAR_ERR();
10991098
if (stmt->methods->executer(stmt)) {

ext/pdo/pdo_stmt.c

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,11 +1736,22 @@ PHP_METHOD(PDOStatement, getColumnMeta)
17361736

17371737
/* {{{ Changes the default fetch mode for subsequent fetches (params have different meaning for different fetch modes) */
17381738

1739-
bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, uint32_t total_num_args, zend_long fetch_mode,
1740-
uint32_t mode_arg_num, zval *arg1, uint32_t arg1_arg_num, HashTable *constructor_args,
1741-
uint32_t constructor_arg_num)
1739+
bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_arg_num,
1740+
zval *args, uint32_t variadic_num_args)
17421741
{
17431742
int flags = 0;
1743+
uint32_t arg1_arg_num = mode_arg_num + 1;
1744+
uint32_t constructor_arg_num = mode_arg_num + 2;
1745+
uint32_t total_num_args = mode_arg_num + variadic_num_args;
1746+
zval arg1, constructor_args;
1747+
1748+
/* Assign variadic params to dedicated ones */
1749+
if (variadic_num_args >= 1) {
1750+
arg1 = args[0];
1751+
if (variadic_num_args >= 1) {
1752+
constructor_args = args[1];
1753+
}
1754+
}
17441755

17451756
switch (stmt->default_fetch_type) {
17461757
case PDO_FETCH_INTO:
@@ -1755,13 +1766,13 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, uint32_t total_num_args, zend_l
17551766

17561767
stmt->default_fetch_type = PDO_FETCH_BOTH;
17571768

1758-
flags = fetch_mode & PDO_FETCH_FLAGS;
1769+
flags = mode & PDO_FETCH_FLAGS;
17591770

1760-
if (!pdo_stmt_verify_mode(stmt, fetch_mode, mode_arg_num, false)) {
1771+
if (!pdo_stmt_verify_mode(stmt, mode, mode_arg_num, false)) {
17611772
return false;
17621773
}
17631774

1764-
switch (fetch_mode & ~PDO_FETCH_FLAGS) {
1775+
switch (mode & ~PDO_FETCH_FLAGS) {
17651776
case PDO_FETCH_USE_DEFAULT:
17661777
case PDO_FETCH_LAZY:
17671778
case PDO_FETCH_ASSOC:
@@ -1773,7 +1784,7 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, uint32_t total_num_args, zend_l
17731784
case PDO_FETCH_KEY_PAIR:
17741785
if (total_num_args != mode_arg_num) {
17751786
zend_string *func = get_active_function_or_method_name();
1776-
zend_argument_count_error("%s() expects exactly %d argument for the fetch mode provided, %d given",
1787+
zend_argument_count_error("%s() expects exactly %d arguments for the fetch mode provided, %d given",
17771788
ZSTR_VAL(func), mode_arg_num, total_num_args);
17781789
zend_string_release(func);
17791790
return false;
@@ -1783,57 +1794,68 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, uint32_t total_num_args, zend_l
17831794
case PDO_FETCH_COLUMN:
17841795
if (total_num_args != arg1_arg_num) {
17851796
zend_string *func = get_active_function_or_method_name();
1786-
zend_argument_count_error("%s() expects exactly %d argument for the fetch mode provided, %d given",
1797+
zend_argument_count_error("%s() expects exactly %d arguments for the fetch mode provided, %d given",
17871798
ZSTR_VAL(func), arg1_arg_num, total_num_args);
17881799
zend_string_release(func);
17891800
return false;
17901801
}
1791-
if (Z_TYPE_P(arg1) != IS_LONG) {
1792-
zend_argument_type_error(arg1_arg_num, "must be int, %s given", zend_zval_type_name(arg1));
1802+
/* arg1 is initialized at the start */
1803+
if (Z_TYPE(arg1) != IS_LONG) {
1804+
zend_argument_type_error(arg1_arg_num, "must be int, %s given", zend_zval_type_name(&arg1));
17931805
return false;
17941806
}
1795-
if (Z_LVAL_P(arg1) < 0) {
1807+
if (Z_LVAL(arg1) < 0) {
17961808
zend_argument_value_error(arg1_arg_num, "must be greater than or equal to 0");
17971809
return false;
17981810
}
1799-
stmt->fetch.column = Z_LVAL_P(arg1);
1811+
stmt->fetch.column = Z_LVAL(arg1);
18001812
break;
18011813

18021814
case PDO_FETCH_CLASS:
18031815
/* Undef constructor arguments */
18041816
ZVAL_UNDEF(&stmt->fetch.cls.ctor_args);
18051817
/* Gets its class name from 1st column */
18061818
if ((flags & PDO_FETCH_CLASSTYPE) == PDO_FETCH_CLASSTYPE) {
1807-
if (arg1 || constructor_args) {
1819+
if (variadic_num_args != 0) {
18081820
zend_string *func = get_active_function_or_method_name();
1809-
zend_argument_count_error("%s() expects exactly %d argument for the fetch mode provided, %d given",
1821+
zend_argument_count_error("%s() expects exactly %d arguments for the fetch mode provided, %d given",
18101822
ZSTR_VAL(func), mode_arg_num, total_num_args);
18111823
zend_string_release(func);
18121824
return false;
18131825
}
18141826
stmt->fetch.cls.ce = NULL;
18151827
} else {
18161828
zend_class_entry *cep;
1817-
1818-
if (!arg1 || total_num_args > constructor_arg_num) {
1829+
if (variadic_num_args == 0) {
1830+
zend_string *func = get_active_function_or_method_name();
1831+
zend_argument_count_error("%s() expects at least %d arguments for the fetch mode provided, %d given",
1832+
ZSTR_VAL(func), arg1_arg_num, total_num_args);
1833+
zend_string_release(func);
1834+
return false;
1835+
}
1836+
/* constructor_arguments can be null/not passed */
1837+
if (variadic_num_args > 2) {
18191838
zend_string *func = get_active_function_or_method_name();
1820-
zend_argument_count_error("%s() expects exactly %d argument for the fetch mode provided, %d given",
1839+
zend_argument_count_error("%s() expects at most %d arguments for the fetch mode provided, %d given",
18211840
ZSTR_VAL(func), constructor_arg_num, total_num_args);
18221841
zend_string_release(func);
18231842
return false;
18241843
}
1825-
if (Z_TYPE_P(arg1) != IS_STRING) {
1826-
zend_argument_type_error(arg1_arg_num, "must be string, %s given", zend_zval_type_name(arg1));
1844+
/* arg1 is initialized at the start */
1845+
if (Z_TYPE(arg1) != IS_STRING) {
1846+
zend_argument_type_error(arg1_arg_num, "must be string, %s given", zend_zval_type_name(&arg1));
18271847
return false;
18281848
}
1829-
cep = zend_lookup_class(Z_STR_P(arg1));
1849+
cep = zend_lookup_class(Z_STR(arg1));
18301850
if (!cep) {
18311851
zend_argument_type_error(arg1_arg_num, "must be a valid class");
18321852
return false;
18331853
}
18341854
stmt->fetch.cls.ce = cep;
1835-
if (constructor_args && zend_hash_num_elements(constructor_args)) {
1836-
ZVAL_ARR(&stmt->fetch.cls.ctor_args, zend_array_dup(constructor_args));
1855+
1856+
/* constructor_args is initialized at the start if variadic_num_args == 2 */
1857+
if (variadic_num_args == 2 && zend_hash_num_elements(Z_ARRVAL(constructor_args))) {
1858+
ZVAL_ARR(&stmt->fetch.cls.ctor_args, zend_array_dup(Z_ARRVAL(constructor_args)));
18371859
}
18381860
}
18391861

@@ -1843,44 +1865,45 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, uint32_t total_num_args, zend_l
18431865
case PDO_FETCH_INTO:
18441866
if (total_num_args != arg1_arg_num) {
18451867
zend_string *func = get_active_function_or_method_name();
1846-
zend_argument_count_error("%s() expects exactly %d argument for the fetch mode provided, %d given",
1868+
zend_argument_count_error("%s() expects exactly %d arguments for the fetch mode provided, %d given",
18471869
ZSTR_VAL(func), arg1_arg_num, total_num_args);
18481870
zend_string_release(func);
18491871
return false;
18501872
}
1851-
if (Z_TYPE_P(arg1) != IS_OBJECT) {
1852-
zend_argument_type_error(arg1_arg_num, "must be object, %s given", zend_zval_type_name(arg1));
1873+
/* arg1 is initialized at the start */
1874+
if (Z_TYPE(arg1) != IS_OBJECT) {
1875+
zend_argument_type_error(arg1_arg_num, "must be object, %s given", zend_zval_type_name(&arg1));
18531876
return false;
18541877
}
18551878

1856-
ZVAL_COPY(&stmt->fetch.into, arg1);
1879+
ZVAL_COPY(&stmt->fetch.into, &arg1);
18571880
break;
18581881
default:
18591882
zend_argument_value_error(mode_arg_num, "must be one of the PDO::FETCH_* constants");
18601883
return false;
18611884
}
18621885

1863-
stmt->default_fetch_type = fetch_mode;
1886+
stmt->default_fetch_type = mode;
18641887

18651888
return true;
18661889
}
18671890

18681891
PHP_METHOD(PDOStatement, setFetchMode)
18691892
{
18701893
zend_long fetch_mode;
1871-
zval *arg1 = NULL;
1872-
HashTable *constructor_args = NULL;
1894+
zval *args = NULL;
1895+
uint32_t num_args = 0;
18731896

18741897
/* Support null for constructor arguments for BC */
1875-
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l|z!h!", &fetch_mode, &arg1, &constructor_args) == FAILURE) {
1898+
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l*", &fetch_mode, &args, &num_args) == FAILURE) {
18761899
RETURN_THROWS();
18771900
}
18781901

18791902
PHP_STMT_GET_OBJ;
18801903

18811904
do_fetch_opt_finish(stmt, 1);
18821905

1883-
if (!pdo_stmt_setup_fetch_mode(stmt, ZEND_NUM_ARGS(), fetch_mode, 1, arg1, 2, constructor_args, 3)) {
1906+
if (!pdo_stmt_setup_fetch_mode(stmt, fetch_mode, 1, args, num_args)) {
18841907
RETURN_THROWS();
18851908
}
18861909

ext/pdo/php_pdo_int.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,8 @@ void pdo_dbstmt_free_storage(zend_object *std);
4040
zend_object_iterator *pdo_stmt_iter_get(zend_class_entry *ce, zval *object, int by_ref);
4141
extern zend_object_handlers pdo_dbstmt_object_handlers;
4242
int pdo_stmt_describe_columns(pdo_stmt_t *stmt);
43-
bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, uint32_t total_num_args, zend_long mode,
44-
uint32_t mode_arg_num, zval *arg1, uint32_t arg1_arg_num, HashTable *constructor_args,
45-
uint32_t constructor_arg_num);
43+
bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_arg_num,
44+
zval *args, uint32_t variadic_num_args);
4645

4746
extern zend_object *pdo_row_new(zend_class_entry *ce);
4847
extern const zend_function_entry pdo_row_functions[];

ext/pdo/tests/bug_44173.phpt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ try {
7272

7373
?>
7474
--EXPECT--
75-
PDO::query() expects exactly 2 argument for the fetch mode provided, 4 given
75+
PDO::query() expects exactly 2 arguments for the fetch mode provided, 4 given
7676
PDO::query(): Argument #2 ($fetch_mode) must be of type ?int, string given
77-
PDO::query() expects at most 4 arguments, 5 given
78-
PDO::query() expects exactly 3 argument for the fetch mode provided, 2 given
79-
PDO::query() expects exactly 3 argument for the fetch mode provided, 2 given
80-
PDO::query() expects exactly 4 argument for the fetch mode provided, 2 given
77+
PDO::query() expects at most 4 arguments for the fetch mode provided, 5 given
78+
PDO::query() expects exactly 3 arguments for the fetch mode provided, 2 given
79+
PDO::query() expects exactly 3 arguments for the fetch mode provided, 2 given
80+
PDO::query() expects at least 3 arguments for the fetch mode provided, 2 given

0 commit comments

Comments
 (0)