From 7e6b8407788bbabb4fb1c620192faafeb7b7403a Mon Sep 17 00:00:00 2001 From: Dharman Date: Wed, 14 Oct 2020 23:17:48 +0100 Subject: [PATCH] Consistent error handling in mysqli_poll This error condition should not actually be reachable, but change it to be consistent with the other ones. Also fix a memory leak. Closes GH-6340. --- ext/mysqli/mysqli_nonapi.c | 10 +++++----- ext/mysqli/mysqli_warning.c | 6 +++--- ext/mysqli/tests/mysqli_poll.phpt | 9 +++++++++ 3 files changed, 17 insertions(+), 8 deletions(-) diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 4ffe1c1307..364638c44a 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -740,7 +740,7 @@ 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)) { - zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(intern->zo.ce->name)); + zend_throw_error(NULL, "%s object is already closed", ZSTR_VAL(intern->zo.ce->name)); return FAILURE; } mysql = (MY_MYSQL*) my_res->ptr; @@ -761,12 +761,11 @@ static int mysqlnd_zval_array_from_mysqlnd_array(MYSQLND **in_array, zval *out_a MYSQLND **p = in_array; zval dest_array; zval *elem, *dest_elem; - int ret = 0, i = 0; + int ret = 0; array_init_size(&dest_array, zend_hash_num_elements(Z_ARRVAL_P(out_array))); ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(out_array), elem) { - i++; if (Z_TYPE_P(elem) != IS_OBJECT || !instanceof_function(Z_OBJCE_P(elem), mysqli_link_class_entry)) { continue; @@ -776,8 +775,8 @@ static int mysqlnd_zval_array_from_mysqlnd_array(MYSQLND **in_array, zval *out_a 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 (mysql->mysql == *p) { @@ -867,6 +866,7 @@ PHP_FUNCTION(mysqli_poll) if (e_array != NULL) { if (mysqlnd_zval_array_to_mysqlnd_array(e_array, &new_e_array) == FAILURE) { efree(new_e_array); + efree(new_r_array); RETURN_THROWS(); } } diff --git a/ext/mysqli/mysqli_warning.c b/ext/mysqli/mysqli_warning.c index c99b3df5df..7b1552e5ac 100644 --- a/ext/mysqli/mysqli_warning.c +++ b/ext/mysqli/mysqli_warning.c @@ -201,7 +201,7 @@ static int mysqli_warning_message(mysqli_object *obj, zval *retval, zend_bool qu if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { if (!quiet) { - zend_throw_error(NULL, "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)); } return FAILURE; @@ -221,7 +221,7 @@ static int mysqli_warning_sqlstate(mysqli_object *obj, zval *retval, zend_bool q if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { if (!quiet) { - zend_throw_error(NULL, "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)); } return FAILURE; @@ -241,7 +241,7 @@ static int mysqli_warning_errno(mysqli_object *obj, zval *retval, zend_bool quie if (!obj->ptr || !((MYSQLI_RESOURCE *)(obj->ptr))->ptr) { if (!quiet) { - zend_throw_error(NULL, "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)); } return FAILURE; diff --git a/ext/mysqli/tests/mysqli_poll.phpt b/ext/mysqli/tests/mysqli_poll.phpt index 7ff77f71c8..615c027d68 100644 --- a/ext/mysqli/tests/mysqli_poll.phpt +++ b/ext/mysqli/tests/mysqli_poll.phpt @@ -40,6 +40,14 @@ if (!$IS_MYSQLND) echo $e->getMessage() . \PHP_EOL; } + $link->close(); + $read[0] = get_connection(); + try { + mysqli_poll($read, $error, $reject, 0, 1); + } catch (\Error $e) { + echo $e->getMessage() . \PHP_EOL; + } + function poll_async($offset, $link, $links, $errors, $reject, $exp_ready, $use_oo_syntax) { if ($exp_ready !== ($tmp = mysqli_poll($links, $errors, $reject, 0, 1000))) @@ -116,6 +124,7 @@ if (!$IS_MYSQLND) --EXPECTF-- mysqli_poll(): Argument #4 ($seconds) must be greater than or equal to 0 mysqli_poll(): Argument #5 ($microseconds) must be greater than or equal to 0 +mysqli object is already closed [012 + 6] Rejecting thread %d: 0/ [013 + 6] Rejecting thread %d: 0/ [014 + 6] Rejecting thread %d: 0/ -- 2.40.0