31
31
#include "mysqli_priv.h"
32
32
#include "ext/mysqlnd/mysql_float_to_double.h"
33
33
34
+ #define ERROR_ARG_POS (arg_num ) (getThis() ? (arg_num-1) : (arg_num))
35
+
34
36
35
37
#ifndef MYSQLI_USE_MYSQLND
36
38
/* {{{ mysqli_tx_cor_options_to_string */
@@ -324,19 +326,19 @@ PHP_FUNCTION(mysqli_stmt_bind_param)
324
326
MYSQLI_FETCH_RESOURCE_STMT (stmt , mysql_stmt , MYSQLI_STATUS_VALID );
325
327
326
328
if (!types_len ) {
327
- php_error_docref ( NULL , E_WARNING , "Invalid type or no types specified " );
328
- RETURN_FALSE ;
329
+ zend_argument_value_error ( ERROR_ARG_POS ( 2 ), "cannot be empty " );
330
+ RETURN_THROWS () ;
329
331
}
330
332
331
333
if (types_len != (size_t ) argc ) {
332
334
/* number of bind variables doesn't match number of elements in type definition string */
333
- php_error_docref ( NULL , E_WARNING , "Number of elements in type definition string doesn't match number of bind variables" );
334
- RETURN_FALSE ;
335
+ zend_argument_count_error ( "Number of elements in type definition string doesn't match number of bind variables" );
336
+ RETURN_THROWS () ;
335
337
}
336
338
337
339
if (types_len != mysql_stmt_param_count (stmt -> stmt )) {
338
- php_error_docref ( NULL , E_WARNING , "Number of variables doesn't match number of parameters in prepared statement" );
339
- RETURN_FALSE ;
340
+ zend_argument_count_error ( "Number of variables doesn't match number of parameters in prepared statement" );
341
+ RETURN_THROWS () ;
340
342
}
341
343
342
344
RETVAL_BOOL (!mysqli_stmt_bind_param_do_bind (stmt , argc , args , types , getThis () ? 1 : 2 ));
@@ -557,8 +559,8 @@ PHP_FUNCTION(mysqli_stmt_bind_result)
557
559
MYSQLI_FETCH_RESOURCE_STMT (stmt , mysql_stmt , MYSQLI_STATUS_VALID );
558
560
559
561
if ((uint32_t )argc != mysql_stmt_field_count (stmt -> stmt )) {
560
- php_error_docref ( NULL , E_WARNING , "Number of bind variables doesn't match number of fields in prepared statement" );
561
- RETURN_FALSE ;
562
+ zend_argument_count_error ( "Number of bind variables doesn't match number of fields in prepared statement" );
563
+ RETURN_THROWS () ;
562
564
}
563
565
564
566
rc = mysqli_stmt_bind_result_do_bind (stmt , args , argc );
@@ -729,14 +731,21 @@ PHP_FUNCTION(mysqli_data_seek)
729
731
RETURN_THROWS ();
730
732
}
731
733
734
+ if (offset < 0 ) {
735
+ zend_argument_value_error (ERROR_ARG_POS (2 ), "must be greater than or equal to 0" );
736
+ RETURN_THROWS ();
737
+ }
738
+
732
739
MYSQLI_FETCH_RESOURCE (result , MYSQL_RES * , mysql_result , "mysqli_result" , MYSQLI_STATUS_VALID );
733
740
734
741
if (mysqli_result_is_unbuffered (result )) {
742
+ // TODO Promoto to Exception?
735
743
php_error_docref (NULL , E_WARNING , "Function cannot be used with MYSQL_USE_RESULT" );
736
744
RETURN_FALSE ;
737
745
}
738
746
739
- if (offset < 0 || (uint64_t )offset >= mysql_num_rows (result )) {
747
+ if ((uint64_t )offset >= mysql_num_rows (result )) {
748
+ // TODO Warning/Exception?
740
749
RETURN_FALSE ;
741
750
}
742
751
@@ -1181,9 +1190,15 @@ PHP_FUNCTION(mysqli_fetch_field_direct)
1181
1190
RETURN_THROWS ();
1182
1191
}
1183
1192
1193
+ if (offset < 0 ) {
1194
+ zend_argument_value_error (ERROR_ARG_POS (2 ), "must be greater than or equal to 0" );
1195
+ RETURN_THROWS ();
1196
+ }
1197
+
1184
1198
MYSQLI_FETCH_RESOURCE (result , MYSQL_RES * , mysql_result , "mysqli_result" , MYSQLI_STATUS_VALID );
1185
1199
1186
- if (offset < 0 || offset >= (zend_long ) mysql_num_fields (result )) {
1200
+ if (offset >= (zend_long ) mysql_num_fields (result )) {
1201
+ // TODO ValueError?
1187
1202
php_error_docref (NULL , E_WARNING , "Field offset is invalid for resultset" );
1188
1203
RETURN_FALSE ;
1189
1204
}
@@ -1215,6 +1230,7 @@ PHP_FUNCTION(mysqli_fetch_lengths)
1215
1230
1216
1231
MYSQLI_FETCH_RESOURCE (result , MYSQL_RES * , mysql_result , "mysqli_result" , MYSQLI_STATUS_VALID );
1217
1232
1233
+ // TODO Warning?
1218
1234
if (!(ret = mysql_fetch_lengths (result ))) {
1219
1235
RETURN_FALSE ;
1220
1236
}
@@ -1260,9 +1276,16 @@ PHP_FUNCTION(mysqli_field_seek)
1260
1276
if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "Ol" , & mysql_result , mysqli_result_class_entry , & fieldnr ) == FAILURE ) {
1261
1277
RETURN_THROWS ();
1262
1278
}
1279
+
1280
+ if (fieldnr < 0 ) {
1281
+ zend_argument_value_error (ERROR_ARG_POS (2 ), "must be greater than or equal to 0" );
1282
+ RETURN_THROWS ();
1283
+ }
1284
+
1263
1285
MYSQLI_FETCH_RESOURCE (result , MYSQL_RES * , mysql_result , "mysqli_result" , MYSQLI_STATUS_VALID );
1264
1286
1265
- if (fieldnr < 0 || (uint32_t )fieldnr >= mysql_num_fields (result )) {
1287
+ if ((uint32_t )fieldnr >= mysql_num_fields (result )) {
1288
+ // TODO ValueError?
1266
1289
php_error_docref (NULL , E_WARNING , "Invalid field offset" );
1267
1290
RETURN_FALSE ;
1268
1291
}
@@ -1499,13 +1522,14 @@ PHP_FUNCTION(mysqli_kill)
1499
1522
if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "Ol" , & mysql_link , mysqli_link_class_entry , & processid ) == FAILURE ) {
1500
1523
RETURN_THROWS ();
1501
1524
}
1502
- MYSQLI_FETCH_RESOURCE_CONN (mysql , mysql_link , MYSQLI_STATUS_VALID );
1503
1525
1504
1526
if (processid <= 0 ) {
1505
- php_error_docref ( NULL , E_WARNING , "processid should have positive value " );
1506
- RETURN_FALSE ;
1527
+ zend_argument_value_error ( ERROR_ARG_POS ( 2 ), "must be greater than 0 " );
1528
+ RETURN_THROWS () ;
1507
1529
}
1508
1530
1531
+ MYSQLI_FETCH_RESOURCE_CONN (mysql , mysql_link , MYSQLI_STATUS_VALID );
1532
+
1509
1533
if (mysql_kill (mysql -> mysql , processid )) {
1510
1534
MYSQLI_REPORT_MYSQL_ERROR (mysql -> mysql );
1511
1535
RETURN_FALSE ;
@@ -1601,6 +1625,7 @@ PHP_FUNCTION(mysqli_num_rows)
1601
1625
MYSQLI_FETCH_RESOURCE (result , MYSQL_RES * , mysql_result , "mysqli_result" , MYSQLI_STATUS_VALID );
1602
1626
1603
1627
if (mysqli_result_is_unbuffered_and_not_everything_is_fetched (result )) {
1628
+ // TODO Exception?
1604
1629
php_error_docref (NULL , E_WARNING , "Function cannot be used with MYSQL_USE_RESULT" );
1605
1630
RETURN_LONG (0 );
1606
1631
}
@@ -1922,12 +1947,14 @@ PHP_FUNCTION(mysqli_stmt_send_long_data)
1922
1947
if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "Ols" , & mysql_stmt , mysqli_stmt_class_entry , & param_nr , & data , & data_len ) == FAILURE ) {
1923
1948
RETURN_THROWS ();
1924
1949
}
1950
+
1925
1951
MYSQLI_FETCH_RESOURCE_STMT (stmt , mysql_stmt , MYSQLI_STATUS_VALID );
1926
1952
1927
1953
if (param_nr < 0 ) {
1928
- php_error_docref ( NULL , E_WARNING , "Invalid parameter number " );
1929
- RETURN_FALSE ;
1954
+ zend_argument_value_error ( ERROR_ARG_POS ( 2 ), "must be greater than or equal to 0 " );
1955
+ RETURN_THROWS () ;
1930
1956
}
1957
+
1931
1958
if (mysql_stmt_send_long_data (stmt -> stmt , param_nr , data , data_len )) {
1932
1959
RETURN_FALSE ;
1933
1960
}
@@ -1984,9 +2011,10 @@ PHP_FUNCTION(mysqli_stmt_data_seek)
1984
2011
if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "Ol" , & mysql_stmt , mysqli_stmt_class_entry , & offset ) == FAILURE ) {
1985
2012
RETURN_THROWS ();
1986
2013
}
2014
+
1987
2015
if (offset < 0 ) {
1988
- php_error_docref ( NULL , E_WARNING , "Offset must be positive " );
1989
- RETURN_FALSE ;
2016
+ zend_argument_value_error ( ERROR_ARG_POS ( 2 ), " must be greater than or equal to 0 " );
2017
+ RETURN_THROWS () ;
1990
2018
}
1991
2019
1992
2020
MYSQLI_FETCH_RESOURCE_STMT (stmt , mysql_stmt , MYSQLI_STATUS_VALID );
@@ -2225,13 +2253,15 @@ PHP_FUNCTION(mysqli_stmt_attr_set)
2225
2253
if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "Oll" , & mysql_stmt , mysqli_stmt_class_entry , & attr , & mode_in ) == FAILURE ) {
2226
2254
RETURN_THROWS ();
2227
2255
}
2228
- MYSQLI_FETCH_RESOURCE_STMT (stmt , mysql_stmt , MYSQLI_STATUS_VALID );
2229
2256
2257
+ /* TODO Improve the mode to depend on the ATTR */
2230
2258
if (mode_in < 0 ) {
2231
- php_error_docref ( NULL , E_WARNING , "Mode should be non-negative, " ZEND_LONG_FMT " passed" , mode_in );
2232
- RETURN_FALSE ;
2259
+ zend_argument_value_error ( ERROR_ARG_POS ( 3 ), "must be greater than or equal to 0" );
2260
+ RETURN_THROWS () ;
2233
2261
}
2234
2262
2263
+ MYSQLI_FETCH_RESOURCE_STMT (stmt , mysql_stmt , MYSQLI_STATUS_VALID );
2264
+
2235
2265
switch (attr ) {
2236
2266
#if MYSQL_VERSION_ID >= 50107
2237
2267
case STMT_ATTR_UPDATE_MAX_LENGTH :
@@ -2244,6 +2274,7 @@ PHP_FUNCTION(mysqli_stmt_attr_set)
2244
2274
mode_p = & mode ;
2245
2275
break ;
2246
2276
}
2277
+
2247
2278
#ifndef MYSQLI_USE_MYSQLND
2248
2279
if (mysql_stmt_attr_set (stmt -> stmt , attr , mode_p )) {
2249
2280
#else
@@ -2262,20 +2293,36 @@ PHP_FUNCTION(mysqli_stmt_attr_get)
2262
2293
zval * mysql_stmt ;
2263
2294
unsigned long value = 0 ;
2264
2295
zend_long attr ;
2265
- int rc ;
2266
2296
2267
2297
if (zend_parse_method_parameters (ZEND_NUM_ARGS (), getThis (), "Ol" , & mysql_stmt , mysqli_stmt_class_entry , & attr ) == FAILURE ) {
2268
2298
RETURN_THROWS ();
2269
2299
}
2270
2300
MYSQLI_FETCH_RESOURCE_STMT (stmt , mysql_stmt , MYSQLI_STATUS_VALID );
2271
2301
2272
- if ((rc = mysql_stmt_attr_get (stmt -> stmt , attr , & value ))) {
2273
- RETURN_FALSE ;
2302
+ switch (attr ) {
2303
+ #if MYSQL_VERSION_ID >= 50107
2304
+ case STMT_ATTR_UPDATE_MAX_LENGTH :
2305
+ #endif
2306
+ case STMT_ATTR_CURSOR_TYPE :
2307
+ case STMT_ATTR_PREFETCH_ROWS :
2308
+ break ;
2309
+ default :
2310
+ zend_argument_value_error (ERROR_ARG_POS (2 ), "must be one of "
2311
+ #if MYSQL_VERSION_ID >= 50107
2312
+ "MYSQLI_STMT_ATTR_UPDATE_MAX_LENGTH, "
2313
+ #endif
2314
+ "MYSQLI_STMT_ATTR_PREFETCH_ROWS, or STMT_ATTR_CURSOR_TYPE" );
2315
+ RETURN_THROWS ();
2274
2316
}
2275
2317
2318
+ /* Success corresponds to 0 return value and a non-zero value
2319
+ * should only happen if the attr/option is unknown */
2320
+ ZEND_ASSERT (mysql_stmt_attr_get (stmt -> stmt , attr , & value ) == 0 );
2321
+
2276
2322
#if MYSQL_VERSION_ID >= 50107
2277
- if (attr == STMT_ATTR_UPDATE_MAX_LENGTH )
2323
+ if (attr == STMT_ATTR_UPDATE_MAX_LENGTH ) {
2278
2324
value = * ((my_bool * )& value );
2325
+ }
2279
2326
#endif
2280
2327
RETURN_LONG ((unsigned long )value );
2281
2328
}
0 commit comments