Skip to content

Promote mysqli warnings to exceptions #5058

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions ext/mysqli/mysqli.c
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ zval *mysqli_read_property(zend_object *object, zend_string *name, int type, voi
}

if (hnd) {
if (hnd->read_func(obj, rv, type == BP_VAR_IS) == SUCCESS || type != BP_VAR_IS) {
if (hnd->read_func(obj, rv, type == BP_VAR_IS) == SUCCESS) {
retval = rv;
} else {
retval = &EG(uninitialized_zval);
Expand Down Expand Up @@ -409,6 +409,7 @@ HashTable *mysqli_object_get_debug_info(zend_object *object, int *is_temp)
ZEND_HASH_FOREACH_PTR(props, entry) {
zval rv;
zval *value;

value = mysqli_read_property(object, entry->name, BP_VAR_IS, 0, &rv);
if (value != &EG(uninitialized_zval)) {
zend_hash_add(retval, entry->name, value);
Expand Down Expand Up @@ -470,7 +471,7 @@ static MYSQLND *mysqli_convert_zv_to_mysqlnd(zval * zv)
mysqli_object *intern = Z_MYSQLI_P(zv);
if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {
/* We know that we have a mysqli object, so this failure should be emitted */
php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(intern->zo.ce->name));
zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(intern->zo.ce->name));
return NULL;
}
mysql = (MY_MYSQL *)(my_res->ptr);
Expand Down
22 changes: 14 additions & 8 deletions ext/mysqli/mysqli_nonapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ static int mysqlnd_zval_array_to_mysqlnd_array(zval *in_array, MYSQLND ***out_ar
int i = 0, current = 0;

if (Z_TYPE_P(in_array) != IS_ARRAY) {
return 0;
return SUCCESS;
}
*out_array = ecalloc(zend_hash_num_elements(Z_ARRVAL_P(in_array)) + 1, sizeof(MYSQLND *));
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(in_array), elem) {
Expand All @@ -744,18 +744,18 @@ static int mysqlnd_zval_array_to_mysqlnd_array(zval *in_array, MYSQLND ***out_ar
MYSQLI_RESOURCE *my_res;
mysqli_object *intern = Z_MYSQLI_P(elem);
if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {
php_error_docref(NULL, E_WARNING, "[%d] Couldn't fetch %s", i, ZSTR_VAL(intern->zo.ce->name));
continue;
zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(intern->zo.ce->name));
return FAILURE;
}
mysql = (MY_MYSQL*) my_res->ptr;
if (MYSQLI_STATUS_VALID && my_res->status < MYSQLI_STATUS_VALID) {
php_error_docref(NULL, E_WARNING, "Invalid object %d or resource %s", i, ZSTR_VAL(intern->zo.ce->name));
continue;
zend_throw_error(NULL, "%s object is not fully initialized", ZSTR_VAL(intern->zo.ce->name));
return FAILURE;
}
(*out_array)[current++] = mysql->mysql;
}
} ZEND_HASH_FOREACH_END();
return 0;
return SUCCESS;
}
/* }}} */

Expand Down Expand Up @@ -859,10 +859,16 @@ PHP_FUNCTION(mysqli_poll)
}

if (r_array != NULL) {
mysqlnd_zval_array_to_mysqlnd_array(r_array, &new_r_array);
if (mysqlnd_zval_array_to_mysqlnd_array(r_array, &new_r_array) == FAILURE) {
efree(new_r_array);
RETURN_THROWS();
}
}
if (e_array != NULL) {
mysqlnd_zval_array_to_mysqlnd_array(e_array, &new_e_array);
if (mysqlnd_zval_array_to_mysqlnd_array(e_array, &new_e_array) == FAILURE) {
efree(new_e_array);
RETURN_THROWS();
}
}

ret = mysqlnd_poll(new_r_array, new_e_array, &new_dont_poll_array, sec, usec, &desc_num);
Expand Down
12 changes: 4 additions & 8 deletions ext/mysqli/mysqli_prop.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,17 @@
#define CHECK_STATUS(value, quiet) \
if (!obj->ptr || ((MYSQLI_RESOURCE *)obj->ptr)->status < value ) { \
if (!quiet) { \
php_error_docref(NULL, E_WARNING, "Property access is not allowed yet"); \
zend_throw_error(NULL, "Property access is not allowed yet"); \
} \
ZVAL_FALSE(retval); \
return FAILURE; \
} \

#define MYSQLI_GET_MYSQL(statusval) \
MYSQL *p; \
if (!obj->ptr || !(MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { \
if (!quiet) { \
php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); \
zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(obj->zo.ce->name)); \
} \
ZVAL_FALSE(retval);\
return FAILURE; \
} else { \
CHECK_STATUS(statusval, quiet);\
Expand All @@ -53,9 +51,8 @@ if (!obj->ptr || !(MY_MYSQL *)((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { \
MYSQL_RES *p; \
if (!obj->ptr) { \
if (!quiet) { \
php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); \
zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(obj->zo.ce->name)); \
} \
ZVAL_NULL(retval);\
return FAILURE; \
} else { \
CHECK_STATUS(statusval, quiet);\
Expand All @@ -66,9 +63,8 @@ if (!obj->ptr) { \
MYSQL_STMT *p; \
if (!obj->ptr) { \
if (!quiet) { \
php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name)); \
zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(obj->zo.ce->name)); \
} \
ZVAL_NULL(retval);\
return FAILURE; \
} else { \
CHECK_STATUS(statusval, quiet); \
Expand Down
9 changes: 3 additions & 6 deletions ext/mysqli/mysqli_warning.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,8 @@ static int mysqli_warning_message(mysqli_object *obj, zval *retval, zend_bool qu

if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) {
if (!quiet) {
php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name));
zend_throw_error(NULL, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name));
}
ZVAL_NULL(retval);

return FAILURE;
}
Expand All @@ -224,9 +223,8 @@ static int mysqli_warning_sqlstate(mysqli_object *obj, zval *retval, zend_bool q

if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) {
if (!quiet) {
php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name));
zend_throw_error(NULL, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name));
}
ZVAL_NULL(retval);

return FAILURE;
}
Expand All @@ -245,9 +243,8 @@ static int mysqli_warning_errno(mysqli_object *obj, zval *retval, zend_bool quie

if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) {
if (!quiet) {
php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name));
zend_throw_error(NULL, "Couldn't fetch %s", ZSTR_VAL(obj->zo.ce->name));
}
ZVAL_NULL(retval);

return FAILURE;
}
Expand Down
16 changes: 8 additions & 8 deletions ext/mysqli/php_mysqli_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -246,26 +246,26 @@ extern void php_mysqli_fetch_into_hash_aux(zval *return_value, MYSQL_RES * resul
MYSQLI_RESOURCE *my_res; \
mysqli_object *intern = Z_MYSQLI_P(__id); \
if (!(my_res = (MYSQLI_RESOURCE *)intern->ptr)) {\
php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(intern->zo.ce->name));\
RETURN_FALSE;\
zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(intern->zo.ce->name));\
RETURN_THROWS();\
}\
__ptr = (__type)my_res->ptr; \
if (__check && my_res->status < __check) { \
php_error_docref(NULL, E_WARNING, "invalid object or resource %s\n", ZSTR_VAL(intern->zo.ce->name)); \
RETURN_FALSE;\
zend_throw_error(NULL, "%s object is not fully initialized", ZSTR_VAL(intern->zo.ce->name)); \
RETURN_THROWS();\
}\
}

#define MYSQLI_FETCH_RESOURCE_BY_OBJ(__ptr, __type, __obj, __name, __check) \
{ \
MYSQLI_RESOURCE *my_res; \
if (!(my_res = (MYSQLI_RESOURCE *)(__obj->ptr))) {\
php_error_docref(NULL, E_WARNING, "Couldn't fetch %s", ZSTR_VAL(intern->zo.ce->name));\
return;\
}\
zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(intern->zo.ce->name));\
return;\
}\
__ptr = (__type)my_res->ptr; \
if (__check && my_res->status < __check) { \
php_error_docref(NULL, E_WARNING, "invalid object or resource %s\n", ZSTR_VAL(intern->zo.ce->name)); \
zend_throw_error(NULL, "%s object is not fully initialized", ZSTR_VAL(intern->zo.ce->name)); \
return;\
}\
}
Expand Down
10 changes: 6 additions & 4 deletions ext/mysqli/tests/bug28817.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,11 @@ require_once('skipifconnectfailure.inc');
$mysql = new my_mysql();

var_dump($mysql->p_test);
var_dump($mysql->errno);
try {
$mysql->errno;
} catch (Error $exception) {
echo $exception->getMessage() . "\n";
}

$mysql->connect($host, $user, $passwd, $db, $port, $socket);
$mysql->select_db("nonexistingdb");
Expand All @@ -38,7 +42,5 @@ array(2) {
[1]=>
%s(3) "bar"
}

Warning: main(): Couldn't fetch my_mysql in %s on line %d
bool(false)
my_mysql object is already closed
bool(true)
17 changes: 12 additions & 5 deletions ext/mysqli/tests/bug36420.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,22 @@ $mysqli = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket);
$result = $mysqli->query('select 1');

$result->close();
echo $result->num_rows;
try {
$result->num_rows;
} catch (Error $exception) {
echo $exception->getMessage() . "\n";
}

$mysqli->close();
echo $result->num_rows;
try {
$result->num_rows;
} catch (Error $exception) {
echo $exception->getMessage() . "\n";
}

echo "Done\n";
?>
--EXPECTF--
Warning: main(): Couldn't fetch mysqli_result in %s on line %d

Warning: main(): Couldn't fetch mysqli_result in %s on line %d
mysqli_result object is already closed
mysqli_result object is already closed
Done
28 changes: 18 additions & 10 deletions ext/mysqli/tests/bug36802.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -15,27 +15,35 @@ Bug #36802 (crashes with with mysqli_set_charset())

/* following operations should not work */
if (method_exists($mysql, 'set_charset')) {
$x[0] = @$mysql->set_charset('utf8');
try {
$mysql->set_charset('utf8');
} catch (Error $exception) {
echo $exception->getMessage() . "\n";
}
} else {
$x[0] = false;
}
$x[1] = @$mysql->query("SELECT 'foo' FROM DUAL");

try {
$mysql->query("SELECT 'foo' FROM DUAL");
} catch (Error $exception) {
echo $exception->getMessage() . "\n";
}

/* following operations should work */
$x[2] = ($mysql->client_version > 0);
$x[3] = $mysql->errno;
$x[1] = ($mysql->client_version > 0);
$x[2] = $mysql->errno;

$mysql->close();

var_dump($x);
?>
--EXPECT--
array(4) {
[0]=>
bool(false)
mysqli object is not fully initialized
mysqli object is not fully initialized
array(2) {
[1]=>
bool(false)
[2]=>
bool(true)
[3]=>
[2]=>
int(0)
}
16 changes: 6 additions & 10 deletions ext/mysqli/tests/bug63398.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,14 @@ mysqli_close($link);
$read = $error = $reject = array();
$read[] = $error[] = $reject[] = $link;

mysqli_poll($read, $error, $reject, 1);
try {
mysqli_poll($read, $error, $reject, 1);
} catch (Error $exception) {
echo $exception->getMessage() . "\n";
}

echo "okey";
?>
--EXPECTF--
Warning: mysqli_poll(): [1] Couldn't fetch mysqli in %sbug63398.php on line %d

Warning: mysqli_poll(): [1] Couldn't fetch mysqli in %sbug63398.php on line %d

Warning: mysqli_poll(): No stream arrays were passed in %sbug63398.php on line %d

Warning: mysqli_poll(): [1] Couldn't fetch mysqli in %sbug63398.php on line %d

Warning: mysqli_poll(): [1] Couldn't fetch mysqli in %sbug63398.php on line %d
mysqli object is already closed
okey
7 changes: 6 additions & 1 deletion ext/mysqli/tests/bug73462.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ require_once('skipifconnectfailure.inc');

/* Failed connection to invalid host */
$mysql_2 = @new mysqli(' !!! invalid !!! ', $user, $passwd, $db);
@$mysql_2->close();
try {
$mysql_2->close();
} catch (Error $exception) {
echo $exception->getMessage() . "\n";
}

/* Re-use persistent connection */
$mysql_3 = new mysqli('p:'.$host, $user, $passwd, $db);
Expand All @@ -38,4 +42,5 @@ require_once('skipifconnectfailure.inc');
print "done!";
?>
--EXPECT--
mysqli object is already closed
done!
14 changes: 8 additions & 6 deletions ext/mysqli/tests/bug75448.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,11 @@ require_once('skipifconnectfailure.inc');
require_once 'connect.inc';
$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket);
mysqli_close($link);
$stmt = mysqli_prepare($link, 'SELECT VERSION()');
var_dump($stmt);
?>
--EXPECTF--
Warning: mysqli_prepare(): Couldn't fetch mysqli in %s on line %d
bool(false)

try {
mysqli_prepare($link, 'SELECT VERSION()');
} catch (Error $exception) {
echo $exception->getMessage() . "\n";
}
--EXPECT--
mysqli object is already closed
8 changes: 6 additions & 2 deletions ext/mysqli/tests/mysqli_affected_rows.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,11 @@ mysqli_affected_rows()

mysqli_close($link);

if (false !== ($tmp = @mysqli_affected_rows($link)))
printf("[033] Expecting false, got %s/%s\n", gettype($tmp), $tmp);
try {
mysqli_affected_rows($link);
} catch (Error $exception) {
echo $exception->getMessage() . "\n";
}

print "done!";
?>
Expand All @@ -120,4 +123,5 @@ mysqli_affected_rows()
require_once("clean_table.inc");
?>
--EXPECT--
mysqli object is already closed
done!
Loading