37
37
#define PHP_STMT_GET_OBJ \
38
38
pdo_stmt_t *stmt = Z_PDO_STMT_P(ZEND_THIS); \
39
39
if (!stmt->dbh) { \
40
- zend_throw_error(NULL, "PDO Object is uninitialized"); \
40
+ zend_throw_error(NULL, "PDO object is uninitialized"); \
41
41
RETURN_THROWS(); \
42
42
} \
43
43
@@ -260,7 +260,7 @@ static int really_register_bound_param(struct pdo_bound_param_data *param, pdo_s
260
260
261
261
for (i = 0 ; i < stmt -> column_count ; i ++ ) {
262
262
if (ZSTR_LEN (stmt -> columns [i ].name ) == ZSTR_LEN (param -> name ) &&
263
- strncmp (ZSTR_VAL (stmt -> columns [i ].name ), ZSTR_VAL (param -> name ), ZSTR_LEN (param -> name ) + 1 ) == 0 ) {
263
+ strncmp (ZSTR_VAL (stmt -> columns [i ].name ), ZSTR_VAL (param -> name ), ZSTR_LEN (param -> name ) + 1 ) == 0 ) {
264
264
param -> paramno = i ;
265
265
break ;
266
266
}
@@ -404,9 +404,9 @@ PHP_METHOD(PDOStatement, execute)
404
404
405
405
if (PDO_PLACEHOLDER_NONE == stmt -> supports_placeholders ) {
406
406
/* handle the emulated parameter binding,
407
- * stmt->active_query_string holds the query with binds expanded and
407
+ * stmt->active_query_string holds the query with binds expanded and
408
408
* quoted.
409
- */
409
+ */
410
410
411
411
/* string is leftover from previous calls so PDOStatement::debugDumpParams() can access */
412
412
if (stmt -> active_query_string && stmt -> active_query_string != stmt -> query_string ) {
@@ -730,7 +730,7 @@ static void do_fetch_opt_finish(pdo_stmt_t *stmt, int free_ctor_agrs) /* {{{ */
730
730
/* fci.size is used to check if it is valid */
731
731
if (stmt -> fetch .cls .fci .size && stmt -> fetch .cls .fci .params ) {
732
732
if (!Z_ISUNDEF (stmt -> fetch .cls .ctor_args )) {
733
- /* Added to free constructor arguments */
733
+ /* Added to free constructor arguments */
734
734
zend_fcall_info_args_clear (& stmt -> fetch .cls .fci , 1 );
735
735
} else {
736
736
efree (stmt -> fetch .cls .fci .params );
@@ -1155,7 +1155,7 @@ static bool pdo_stmt_verify_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode
1155
1155
1156
1156
case PDO_FETCH_LAZY :
1157
1157
if (fetch_all ) {
1158
- zend_value_error ( "Cannot be PDO::FETCH_LAZY in PDOStatement::fetchAll()" );
1158
+ zend_argument_value_error ( mode_arg_num , "cannot be PDO::FETCH_LAZY in PDOStatement::fetchAll()" );
1159
1159
return 0 ;
1160
1160
}
1161
1161
/* fall through */
@@ -1194,7 +1194,7 @@ PHP_METHOD(PDOStatement, fetch)
1194
1194
Z_PARAM_LONG (off )
1195
1195
ZEND_PARSE_PARAMETERS_END ();
1196
1196
1197
- PHP_STMT_GET_OBJ ;
1197
+ PHP_STMT_GET_OBJ ;
1198
1198
PDO_STMT_CLEAR_ERR ();
1199
1199
1200
1200
if (!pdo_stmt_verify_mode (stmt , how , 1 , false)) {
@@ -1578,7 +1578,7 @@ PHP_METHOD(PDOStatement, errorCode)
1578
1578
PHP_METHOD (PDOStatement , errorInfo )
1579
1579
{
1580
1580
int error_count ;
1581
- int error_count_diff = 0 ;
1581
+ int error_count_diff = 0 ;
1582
1582
int error_expected_count = 3 ;
1583
1583
1584
1584
ZEND_PARSE_PARAMETERS_NONE ();
@@ -1743,15 +1743,6 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a
1743
1743
uint32_t arg1_arg_num = mode_arg_num + 1 ;
1744
1744
uint32_t constructor_arg_num = mode_arg_num + 2 ;
1745
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 >= 2 ) {
1752
- constructor_args = args [1 ];
1753
- }
1754
- }
1755
1746
1756
1747
switch (stmt -> default_fetch_type ) {
1757
1748
case PDO_FETCH_INTO :
@@ -1782,7 +1773,7 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a
1782
1773
case PDO_FETCH_BOUND :
1783
1774
case PDO_FETCH_NAMED :
1784
1775
case PDO_FETCH_KEY_PAIR :
1785
- if (total_num_args != mode_arg_num ) {
1776
+ if (variadic_num_args != 0 ) {
1786
1777
zend_string * func = get_active_function_or_method_name ();
1787
1778
zend_argument_count_error ("%s() expects exactly %d arguments for the fetch mode provided, %d given" ,
1788
1779
ZSTR_VAL (func ), mode_arg_num , total_num_args );
@@ -1792,26 +1783,26 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a
1792
1783
break ;
1793
1784
1794
1785
case PDO_FETCH_COLUMN :
1795
- if (total_num_args != arg1_arg_num ) {
1786
+ if (variadic_num_args != 1 ) {
1796
1787
zend_string * func = get_active_function_or_method_name ();
1797
1788
zend_argument_count_error ("%s() expects exactly %d arguments for the fetch mode provided, %d given" ,
1798
1789
ZSTR_VAL (func ), arg1_arg_num , total_num_args );
1799
1790
zend_string_release (func );
1800
1791
return false;
1801
1792
}
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 ));
1793
+ if (Z_TYPE (args [0 ]) != IS_LONG ) {
1794
+ zend_argument_type_error (arg1_arg_num , "must be int, %s given" , zend_zval_type_name (& args [0 ]));
1805
1795
return false;
1806
1796
}
1807
- if (Z_LVAL (arg1 ) < 0 ) {
1797
+ if (Z_LVAL (args [ 0 ] ) < 0 ) {
1808
1798
zend_argument_value_error (arg1_arg_num , "must be greater than or equal to 0" );
1809
1799
return false;
1810
1800
}
1811
- stmt -> fetch .column = Z_LVAL (arg1 );
1801
+ stmt -> fetch .column = Z_LVAL (args [ 0 ] );
1812
1802
break ;
1813
1803
1814
- case PDO_FETCH_CLASS :
1804
+ case PDO_FETCH_CLASS : {
1805
+ HashTable * constructor_args = NULL ;
1815
1806
/* Undef constructor arguments */
1816
1807
ZVAL_UNDEF (& stmt -> fetch .cls .ctor_args );
1817
1808
/* Gets its class name from 1st column */
@@ -1841,27 +1832,38 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a
1841
1832
zend_string_release (func );
1842
1833
return false;
1843
1834
}
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 ));
1835
+ if (Z_TYPE (args [0 ]) != IS_STRING ) {
1836
+ zend_argument_type_error (arg1_arg_num , "must be string, %s given" , zend_zval_type_name (& args [0 ]));
1847
1837
return false;
1848
1838
}
1849
- cep = zend_lookup_class (Z_STR (arg1 ));
1839
+ cep = zend_lookup_class (Z_STR (args [ 0 ] ));
1850
1840
if (!cep ) {
1851
1841
zend_argument_type_error (arg1_arg_num , "must be a valid class" );
1852
1842
return false;
1853
1843
}
1844
+ /* Verify constructor_args (args[1]) is ?array */
1845
+ /* TODO: Improve logic? */
1846
+ if (variadic_num_args == 2 ) {
1847
+ if (Z_TYPE (args [1 ]) != IS_NULL && Z_TYPE (args [1 ]) != IS_ARRAY ) {
1848
+ zend_argument_type_error (constructor_arg_num , "must be ?array, %s given" ,
1849
+ zend_zval_type_name (& args [1 ]));
1850
+ return false;
1851
+ }
1852
+ if (Z_TYPE (args [1 ]) == IS_ARRAY && zend_hash_num_elements (Z_ARRVAL (args [1 ]))) {
1853
+ constructor_args = Z_ARRVAL (args [1 ]);
1854
+ }
1855
+ }
1854
1856
stmt -> fetch .cls .ce = cep ;
1855
1857
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 ) ));
1858
+ /* If constructor arguments are present and not empty */
1859
+ if (constructor_args ) {
1860
+ ZVAL_ARR (& stmt -> fetch .cls .ctor_args , zend_array_dup (constructor_args ));
1859
1861
}
1860
1862
}
1861
1863
1862
1864
do_fetch_class_prepare (stmt );
1863
1865
break ;
1864
-
1866
+ }
1865
1867
case PDO_FETCH_INTO :
1866
1868
if (total_num_args != arg1_arg_num ) {
1867
1869
zend_string * func = get_active_function_or_method_name ();
@@ -1870,13 +1872,12 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a
1870
1872
zend_string_release (func );
1871
1873
return false;
1872
1874
}
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 ));
1875
+ if (Z_TYPE (args [0 ]) != IS_OBJECT ) {
1876
+ zend_argument_type_error (arg1_arg_num , "must be object, %s given" , zend_zval_type_name (& args [0 ]));
1876
1877
return false;
1877
1878
}
1878
1879
1879
- ZVAL_COPY (& stmt -> fetch .into , & arg1 );
1880
+ ZVAL_COPY (& stmt -> fetch .into , & args [ 0 ] );
1880
1881
break ;
1881
1882
default :
1882
1883
zend_argument_value_error (mode_arg_num , "must be one of the PDO::FETCH_* constants" );
@@ -1892,7 +1893,7 @@ PHP_METHOD(PDOStatement, setFetchMode)
1892
1893
{
1893
1894
zend_long fetch_mode ;
1894
1895
zval * args = NULL ;
1895
- uint32_t num_args = 0 ;
1896
+ uint32_t num_args = 0 ;
1896
1897
1897
1898
/* Support null for constructor arguments for BC */
1898
1899
if (zend_parse_parameters (ZEND_NUM_ARGS (), "l*" , & fetch_mode , & args , & num_args ) == FAILURE ) {
@@ -2010,7 +2011,6 @@ PHP_METHOD(PDOStatement, debugDumpParams)
2010
2011
2011
2012
PHP_STMT_GET_OBJ ;
2012
2013
2013
- /* TODO: Change to assertion? */
2014
2014
if (out == NULL ) {
2015
2015
RETURN_FALSE ;
2016
2016
}
@@ -2340,7 +2340,7 @@ static zval *row_prop_read(zend_object *object, zend_string *name, int type, voi
2340
2340
* numbers */
2341
2341
for (colno = 0 ; colno < stmt -> column_count ; colno ++ ) {
2342
2342
if (ZSTR_LEN (stmt -> columns [colno ].name ) == ZSTR_LEN (name ) &&
2343
- strncmp (ZSTR_VAL (stmt -> columns [colno ].name ), ZSTR_VAL (name ), ZSTR_LEN (name )) == 0 ) {
2343
+ strncmp (ZSTR_VAL (stmt -> columns [colno ].name ), ZSTR_VAL (name ), ZSTR_LEN (name )) == 0 ) {
2344
2344
fetch_value (stmt , rv , colno , NULL );
2345
2345
return rv ;
2346
2346
}
@@ -2382,7 +2382,7 @@ static zval *row_dim_read(zend_object *object, zval *member, int type, zval *rv)
2382
2382
* numbers */
2383
2383
for (colno = 0 ; colno < stmt -> column_count ; colno ++ ) {
2384
2384
if (ZSTR_LEN (stmt -> columns [colno ].name ) == Z_STRLEN_P (member ) &&
2385
- strncmp (ZSTR_VAL (stmt -> columns [colno ].name ), Z_STRVAL_P (member ), Z_STRLEN_P (member )) == 0 ) {
2385
+ strncmp (ZSTR_VAL (stmt -> columns [colno ].name ), Z_STRVAL_P (member ), Z_STRLEN_P (member )) == 0 ) {
2386
2386
fetch_value (stmt , rv , colno , NULL );
2387
2387
return rv ;
2388
2388
}
@@ -2424,7 +2424,7 @@ static int row_prop_exists(zend_object *object, zend_string *name, int check_emp
2424
2424
* numbers */
2425
2425
for (colno = 0 ; colno < stmt -> column_count ; colno ++ ) {
2426
2426
if (ZSTR_LEN (stmt -> columns [colno ].name ) == ZSTR_LEN (name ) &&
2427
- strncmp (ZSTR_VAL (stmt -> columns [colno ].name ), ZSTR_VAL (name ), ZSTR_LEN (name )) == 0 ) {
2427
+ strncmp (ZSTR_VAL (stmt -> columns [colno ].name ), ZSTR_VAL (name ), ZSTR_LEN (name )) == 0 ) {
2428
2428
int res ;
2429
2429
zval val ;
2430
2430
@@ -2464,7 +2464,7 @@ static int row_dim_exists(zend_object *object, zval *member, int check_empty)
2464
2464
* numbers */
2465
2465
for (colno = 0 ; colno < stmt -> column_count ; colno ++ ) {
2466
2466
if (ZSTR_LEN (stmt -> columns [colno ].name ) == Z_STRLEN_P (member ) &&
2467
- strncmp (ZSTR_VAL (stmt -> columns [colno ].name ), Z_STRVAL_P (member ), Z_STRLEN_P (member )) == 0 ) {
2467
+ strncmp (ZSTR_VAL (stmt -> columns [colno ].name ), Z_STRVAL_P (member ), Z_STRLEN_P (member )) == 0 ) {
2468
2468
int res ;
2469
2469
zval val ;
2470
2470
0 commit comments