Skip to content

Commit d1d1ac2

Browse files
committed
mysqli_nonapi.c
1 parent f8ab527 commit d1d1ac2

11 files changed

+113
-87
lines changed

ext/mysqli/mysqli.stub.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public function prepare(string $query) {}
165165
* @return mysqli_result|bool
166166
* @alias mysqli_query
167167
*/
168-
public function query(string $query, int $resultmode = MYSQLI_STORE_RESULT) {}
168+
public function query(string $query, int $result_mode = MYSQLI_STORE_RESULT) {}
169169

170170
/**
171171
* @return bool
@@ -644,7 +644,7 @@ function mysqli_prepare(mysqli $mysqli_link, string $query): mysqli_stmt|false {
644644

645645
function mysqli_report(int $flags): bool {}
646646

647-
function mysqli_query(mysqli $mysqli_link, string $query, int $resultmode = MYSQLI_STORE_RESULT): mysqli_result|bool {}
647+
function mysqli_query(mysqli $mysqli_link, string $query, int $result_mode = MYSQLI_STORE_RESULT): mysqli_result|bool {}
648648

649649
function mysqli_real_connect(
650650
mysqli $mysqli_link,

ext/mysqli/mysqli_arginfo.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* This is a generated file, edit the .stub.php file instead.
2-
* Stub hash: 5f26a86bb296305f40cf7ffe033767b9caf430fa */
2+
* Stub hash: 946a60cf957855d603acf0796975d8602a50fbdf */
33

44
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_MASK_EX(arginfo_mysqli_affected_rows, 0, 1, MAY_BE_LONG|MAY_BE_STRING)
55
ZEND_ARG_OBJ_INFO(0, mysql_link, mysqli, 0)
@@ -233,7 +233,7 @@ ZEND_END_ARG_INFO()
233233
ZEND_BEGIN_ARG_WITH_RETURN_OBJ_TYPE_MASK_EX(arginfo_mysqli_query, 0, 2, mysqli_result, MAY_BE_BOOL)
234234
ZEND_ARG_OBJ_INFO(0, mysqli_link, mysqli, 0)
235235
ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0)
236-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, resultmode, IS_LONG, 0, "MYSQLI_STORE_RESULT")
236+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, result_mode, IS_LONG, 0, "MYSQLI_STORE_RESULT")
237237
ZEND_END_ARG_INFO()
238238

239239
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_mysqli_real_connect, 0, 1, _IS_BOOL, 0)
@@ -502,7 +502,7 @@ ZEND_END_ARG_INFO()
502502

503503
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_query, 0, 0, 1)
504504
ZEND_ARG_TYPE_INFO(0, query, IS_STRING, 0)
505-
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, resultmode, IS_LONG, 0, "MYSQLI_STORE_RESULT")
505+
ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, result_mode, IS_LONG, 0, "MYSQLI_STORE_RESULT")
506506
ZEND_END_ARG_INFO()
507507

508508
ZEND_BEGIN_ARG_INFO_EX(arginfo_class_mysqli_real_connect, 0, 0, 0)

ext/mysqli/mysqli_nonapi.c

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "zend_smart_str.h"
2929
#include "php_mysqli_structs.h"
3030
#include "mysqli_priv.h"
31+
#define ERROR_ARG_POS(arg_num) (getThis() ? (arg_num-1) : (arg_num))
3132

3233
#define SAFE_STR(a) ((a)?a:"")
3334

@@ -437,9 +438,9 @@ PHP_FUNCTION(mysqli_fetch_all)
437438
MYSQLI_FETCH_RESOURCE(result, MYSQL_RES *, mysql_result, "mysqli_result", MYSQLI_STATUS_VALID);
438439

439440
if (!mode || (mode & ~MYSQLND_FETCH_BOTH)) {
440-
php_error_docref(NULL, E_WARNING, "Mode can be only MYSQLI_FETCH_NUM, "
441-
"MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH");
442-
RETURN_FALSE;
441+
zend_argument_value_error(ERROR_ARG_POS(2), "must be one of MYSQLI_FETCH_NUM, "
442+
"MYSQLI_FETCH_ASSOC, or MYSQLI_FETCH_BOTH");
443+
RETURN_THROWS();
443444
}
444445

445446
mysqlnd_fetch_all(result, mode, return_value);
@@ -633,16 +634,23 @@ PHP_FUNCTION(mysqli_query)
633634
}
634635

635636
if (!query_len) {
636-
php_error_docref(NULL, E_WARNING, "Empty query");
637-
RETURN_FALSE;
637+
zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty");
638+
RETURN_THROWS();
638639
}
639-
#ifdef MYSQLI_USE_MYSQLND
640-
if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA)) != MYSQLI_STORE_RESULT) {
641-
#else
642-
if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT && (resultmode & ~MYSQLI_ASYNC) != MYSQLI_STORE_RESULT) {
643-
#endif
644-
php_error_docref(NULL, E_WARNING, "Invalid value for resultmode");
645-
RETURN_FALSE;
640+
if ((resultmode & ~MYSQLI_ASYNC) != MYSQLI_USE_RESULT &&
641+
MYSQLI_STORE_RESULT !=
642+
#ifdef MYSQLI_USE_MYSQLND
643+
(resultmode & ~(MYSQLI_ASYNC | MYSQLI_STORE_RESULT_COPY_DATA))
644+
#else
645+
(resultmode & ~MYSQLI_ASYNC)
646+
#endif
647+
) {
648+
zend_argument_value_error(ERROR_ARG_POS(3), "must be one of "
649+
#ifdef MYSQLI_USE_MYSQLND
650+
"MYSQLI_ASYNC,"
651+
#endif
652+
"MYSQLI_USE_RESULT, or MYSQLI_STORE_RESULT");
653+
RETURN_THROWS();
646654
}
647655

648656
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
@@ -724,7 +732,8 @@ static int mysqlnd_zval_array_to_mysqlnd_array(zval *in_array, MYSQLND ***out_ar
724732
i++;
725733
if (Z_TYPE_P(elem) != IS_OBJECT ||
726734
!instanceof_function(Z_OBJCE_P(elem), mysqli_link_class_entry)) {
727-
php_error_docref(NULL, E_WARNING, "Parameter %d not a mysqli object", i);
735+
zend_argument_type_error(i, "must be an instance of mysqli, %s given", zend_zval_type_name(elem));
736+
return FAILURE;
728737
} else {
729738
MY_MYSQL *mysql;
730739
MYSQLI_RESOURCE *my_res;
@@ -833,11 +842,16 @@ PHP_FUNCTION(mysqli_poll)
833842
if (zend_parse_parameters(ZEND_NUM_ARGS(), "a!a!al|l", &r_array, &e_array, &dont_poll_array, &sec, &usec) == FAILURE) {
834843
RETURN_THROWS();
835844
}
836-
if (sec < 0 || usec < 0) {
837-
php_error_docref(NULL, E_WARNING, "Negative values passed for sec and/or usec");
838-
RETURN_FALSE;
845+
if (sec < 0) {
846+
zend_argument_value_error(4, "must be greater than or equal to 0");
847+
RETURN_THROWS();
848+
}
849+
if (usec < 0) {
850+
zend_argument_value_error(5, "must be greater than or equal to 0");
851+
RETURN_THROWS();
839852
}
840853

854+
// TODO Error promotion
841855
if (!r_array && !e_array) {
842856
php_error_docref(NULL, E_WARNING, "No stream arrays were passed");
843857
RETURN_FALSE;
@@ -1154,22 +1168,21 @@ PHP_FUNCTION(mysqli_begin_transaction)
11541168
zend_long flags = TRANS_START_NO_OPT;
11551169
char * name = NULL;
11561170
size_t name_len = -1;
1157-
zend_bool err = FALSE;
11581171

11591172
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "O|ls!", &mysql_link, mysqli_link_class_entry, &flags, &name, &name_len) == FAILURE) {
11601173
RETURN_THROWS();
11611174
}
11621175
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
11631176
if (flags < 0) {
1164-
php_error_docref(NULL, E_WARNING, "Invalid value for parameter flags (" ZEND_LONG_FMT ")", flags);
1165-
err = TRUE;
1177+
zend_argument_value_error(ERROR_ARG_POS(2), "must be MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT"
1178+
/* TODO Only MySQL 5.6 and later */
1179+
", MYSQLI_TRANS_START_READ_ONLY, or MYSQLI_TRANS_START_READ_WRITE"
1180+
);
1181+
RETURN_THROWS();
11661182
}
11671183
if (!name_len) {
1168-
php_error_docref(NULL, E_WARNING, "Savepoint name cannot be empty");
1169-
err = TRUE;
1170-
}
1171-
if (TRUE == err) {
1172-
RETURN_FALSE;
1184+
zend_argument_value_error(ERROR_ARG_POS(3), "cannot be empty");
1185+
RETURN_THROWS();
11731186
}
11741187

11751188
#ifndef MYSQLI_USE_MYSQLND
@@ -1205,15 +1218,15 @@ PHP_FUNCTION(mysqli_savepoint)
12051218
MY_MYSQL *mysql;
12061219
zval *mysql_link;
12071220
char * name = NULL;
1208-
size_t name_len = -1;
1221+
size_t name_len;
12091222

12101223
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) {
12111224
RETURN_THROWS();
12121225
}
12131226
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1214-
if (!name || !name_len) {
1215-
php_error_docref(NULL, E_WARNING, "Savepoint name cannot be empty");
1216-
RETURN_FALSE;
1227+
if (name_len == 0) {
1228+
zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty");
1229+
RETURN_THROWS();
12171230
}
12181231

12191232
#ifndef MYSQLI_USE_MYSQLND
@@ -1233,15 +1246,15 @@ PHP_FUNCTION(mysqli_release_savepoint)
12331246
MY_MYSQL *mysql;
12341247
zval *mysql_link;
12351248
char * name = NULL;
1236-
size_t name_len = -1;
1249+
size_t name_len;
12371250

12381251
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &mysql_link, mysqli_link_class_entry, &name, &name_len) == FAILURE) {
12391252
RETURN_THROWS();
12401253
}
12411254
MYSQLI_FETCH_RESOURCE_CONN(mysql, mysql_link, MYSQLI_STATUS_VALID);
1242-
if (!name || !name_len) {
1243-
php_error_docref(NULL, E_WARNING, "Savepoint name cannot be empty");
1244-
RETURN_FALSE;
1255+
if (name_len == 0) {
1256+
zend_argument_value_error(ERROR_ARG_POS(2), "cannot be empty");
1257+
RETURN_THROWS();
12451258
}
12461259
#ifndef MYSQLI_USE_MYSQLND
12471260
if (mysqli_savepoint_libmysql(mysql->mysql, name, TRUE)) {

ext/mysqli/tests/bug74595.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,6 @@ array(2) {
2020
[1]=>
2121
object(ReflectionParameter)#%d (1) {
2222
["name"]=>
23-
string(10) "resultmode"
23+
string(11) "result_mode"
2424
}
2525
}

ext/mysqli/tests/mysqli_begin_transaction.phpt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,11 @@ if (!have_innodb($link))
7676
}
7777
}
7878

79-
if (!mysqli_begin_transaction($link, -1)) {
80-
printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
79+
try {
80+
mysqli_begin_transaction($link, -1);
81+
printf("[019] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
82+
} catch (\ValueError $e) {
83+
echo $e->getMessage() . \PHP_EOL;
8184
}
8285

8386
if (mysqli_get_server_version($link) >= 50605) {
@@ -96,9 +99,7 @@ if (!have_innodb($link))
9699
<?php
97100
require_once("clean_table.inc");
98101
?>
99-
--EXPECTF--
102+
--EXPECT--
100103
NULL
101-
102-
Warning: mysqli_begin_transaction(): Invalid value for parameter flags (-1) in %s on line %d
103-
[019] [%d]%A
104+
mysqli_begin_transaction(): Argument #2 ($flags) must be MYSQLI_TRANS_START_WITH_CONSISTENT_SNAPSHOT, MYSQLI_TRANS_START_READ_ONLY, or MYSQLI_TRANS_START_READ_WRITE
104105
done!

ext/mysqli/tests/mysqli_fetch_all.phpt

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,12 +71,12 @@ if (!function_exists('mysqli_fetch_all'))
7171
exit(1);
7272
}
7373

74-
do {
75-
$illegal_mode = mt_rand(-10000, 10000);
76-
} while (in_array($illegal_mode, array(MYSQLI_ASSOC, MYSQLI_NUM, MYSQLI_BOTH)));
77-
// NOTE: for BC reasons with ext/mysql, ext/mysqli accepts invalid result modes.
78-
79-
mysqli_fetch_all($res, $illegal_mode);
74+
// Illegal mode
75+
try {
76+
mysqli_fetch_all($res, -10);
77+
} catch (\ValueError $e) {
78+
echo $e->getMessage() . \PHP_EOL;
79+
}
8080
mysqli_free_result($res);
8181

8282
function func_mysqli_fetch_all($link, $engine, $sql_type, $sql_value, $php_value, $offset, $regexp_comparison = NULL) {
@@ -315,7 +315,7 @@ if (!function_exists('mysqli_fetch_all'))
315315
<?php
316316
// require_once("clean_table.inc");
317317
?>
318-
--EXPECTF--
318+
--EXPECT--
319319
[005]
320320
array(2) {
321321
[0]=>
@@ -443,7 +443,6 @@ array(1) {
443443
string(1) "1"
444444
}
445445
}
446-
447-
Warning: mysqli_fetch_all(): Mode can be only MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH in %s on line %d
446+
mysqli_fetch_all(): Argument #2 ($mode) must be one of MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC, or MYSQLI_FETCH_BOTH
448447
mysqli_result object is already closed
449448
done!

ext/mysqli/tests/mysqli_fetch_all_oo.phpt

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,14 @@ if (!function_exists('mysqli_fetch_all'))
8181
exit(1);
8282
}
8383

84-
do {
85-
$illegal_mode = mt_rand(-10000, 10000);
86-
} while (in_array($illegal_mode, array(MYSQLI_ASSOC, MYSQLI_NUM, MYSQLI_BOTH)));
87-
// NOTE: for BC reasons with ext/mysql, ext/mysqli accepts invalid result modes.
88-
$tmp = $res->fetch_all($illegal_mode);
89-
if (false !== $tmp)
90-
printf("[019] Expecting boolean/false although, got %s/%s. [%d] %s\n",
91-
gettype($tmp), $tmp, $mysqli->errno, $mysqli->error);
84+
try {
85+
$tmp = $res->fetch_all(-10);
86+
if (false !== $tmp)
87+
printf("[019] Expecting boolean/false although, got %s/%s. [%d] %s\n",
88+
gettype($tmp), $tmp, $mysqli->errno, $mysqli->error);
89+
} catch (\ValueError $e) {
90+
echo $e->getMessage() . \PHP_EOL;
91+
}
9292

9393
$res->free_result();
9494

@@ -436,7 +436,6 @@ array(1) {
436436
string(1) "1"
437437
}
438438
}
439-
440-
Warning: mysqli_result::fetch_all(): Mode can be only MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC or MYSQLI_FETCH_BOTH in %s on line %d
439+
mysqli_result::fetch_all(): Argument #1 ($result_type) must be one of MYSQLI_FETCH_NUM, MYSQLI_FETCH_ASSOC, or MYSQLI_FETCH_BOTH
441440
mysqli_result object is already closed
442441
done!

ext/mysqli/tests/mysqli_poll.phpt

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,16 @@ if (!$IS_MYSQLND)
3030
printf("[009] Expecting int/0 got %s/%s\n", gettype($tmp), var_export($tmp, true));
3131

3232
$read = $error = $reject = array($link);
33-
if (false !== ($tmp = (mysqli_poll($read, $error, $reject, -1, 1))))
34-
printf("[010] Expecting false got %s/%s\n", gettype($tmp), var_export($tmp, true));
35-
36-
$read = $error = $reject = array($link);
37-
if (false !== ($tmp = (mysqli_poll($read, $error, $reject, 0, -1))))
38-
printf("[011] Expecting false got %s/%s\n", gettype($tmp), var_export($tmp, true));
33+
try {
34+
mysqli_poll($read, $error, $reject, -1, 1);
35+
} catch (\ValueError $e) {
36+
echo $e->getMessage() . \PHP_EOL;
37+
}
38+
try {
39+
mysqli_poll($read, $error, $reject, 0, -1);
40+
} catch (\ValueError $e) {
41+
echo $e->getMessage() . \PHP_EOL;
42+
}
3943

4044
function poll_async($offset, $link, $links, $errors, $reject, $exp_ready, $use_oo_syntax) {
4145

@@ -111,9 +115,8 @@ if (!$IS_MYSQLND)
111115
print "done!";
112116
?>
113117
--EXPECTF--
114-
Warning: mysqli_poll(): Negative values passed for sec and/or usec in %s on line %d
115-
116-
Warning: mysqli_poll(): Negative values passed for sec and/or usec in %s on line %d
118+
mysqli_poll(): Argument #4 ($sec) must be greater than or equal to 0
119+
mysqli_poll(): Argument #5 ($usec) must be greater than or equal to 0
117120
[012 + 6] Rejecting thread %d: 0/
118121
[013 + 6] Rejecting thread %d: 0/
119122
[014 + 6] Rejecting thread %d: 0/

ext/mysqli/tests/mysqli_query.phpt

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@ require_once('skipifconnectfailure.inc');
1212

1313
require('table.inc');
1414

15-
if (false !== ($tmp = @mysqli_query($link, '')))
16-
printf("[002a] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp);
15+
try {
16+
mysqli_query($link, '');
17+
} catch (\ValueError $e) {
18+
echo $e->getMessage() . \PHP_EOL;
19+
}
1720

1821
if (false !== ($tmp = mysqli_query($link, 'THIS IS NOT SQL')))
1922
printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp);
@@ -82,11 +85,11 @@ require_once('skipifconnectfailure.inc');
8285
printf("[012] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
8386
mysqli_free_result($res);
8487

85-
if (false !== ($res = @mysqli_query($link, "SELECT id FROM test ORDER BY id", 1234)))
86-
printf("[013] Invalid mode should return false got %s/%s, [%d] %s\n",
87-
gettype($res), (is_object($res)) ? 'object' : $res,
88-
mysqli_errno($link), mysqli_error($link));
89-
88+
try {
89+
mysqli_query($link, "SELECT id FROM test ORDER BY id", 1234);
90+
} catch (\ValueError $e) {
91+
echo $e->getMessage() . \PHP_EOL;
92+
}
9093

9194
mysqli_close($link);
9295

@@ -113,6 +116,7 @@ if (!mysqli_query($link, "DROP TABLE IF EXISTS test"))
113116
mysqli_close($link);
114117
?>
115118
--EXPECT--
119+
mysqli_query(): Argument #2 ($query) cannot be empty
116120
array(1) {
117121
["valid"]=>
118122
string(30) "this is sql but with semicolon"
@@ -122,5 +126,6 @@ array(1) {
122126
string(1) "a"
123127
}
124128
string(1) "a"
129+
mysqli_query(): Argument #3 ($result_mode) must be one of MYSQLI_ASYNC,MYSQLI_USE_RESULT, or MYSQLI_STORE_RESULT
125130
mysqli object is already closed
126131
done!

0 commit comments

Comments
 (0)