mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Merge branch 'PHP-8.0'
* PHP-8.0: Fix bug #72413: Segfault with get_result and PS cursors
This commit is contained in:
commit
dd008fd124
2 changed files with 61 additions and 22 deletions
|
@ -109,53 +109,84 @@ if (!function_exists('mysqli_stmt_get_result'))
|
|||
|
||||
mysqli_stmt_close($stmt);
|
||||
|
||||
// get_result cannot be used in PS cursor mode
|
||||
if (!$stmt = mysqli_stmt_init($link))
|
||||
printf("[032] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
printf("[030] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2"))
|
||||
printf("[033] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
printf("[031] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
|
||||
if (!mysqli_stmt_attr_set($stmt, MYSQLI_STMT_ATTR_CURSOR_TYPE, MYSQLI_CURSOR_TYPE_READ_ONLY))
|
||||
printf("[032] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
|
||||
if (!mysqli_stmt_execute($stmt))
|
||||
printf("[034] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
printf("[033] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
|
||||
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
|
||||
try {
|
||||
$res = mysqli_stmt_get_result($stmt);
|
||||
// we expect no segfault if we try to fetch a row because get_result should throw an error or return false
|
||||
mysqli_fetch_assoc($res);
|
||||
} catch (\mysqli_sql_exception $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
|
||||
try {
|
||||
$res = $stmt->get_result();
|
||||
// we expect no segfault if we try to fetch a row because get_result should throw an error or return false
|
||||
$res->fetch_assoc();
|
||||
} catch (\mysqli_sql_exception $e) {
|
||||
echo $e->getMessage() . "\n";
|
||||
}
|
||||
mysqli_report(MYSQLI_REPORT_OFF);
|
||||
|
||||
if (!$stmt = mysqli_stmt_init($link))
|
||||
printf("[034] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (!mysqli_stmt_prepare($stmt, "SELECT id, label FROM test ORDER BY id LIMIT 2"))
|
||||
printf("[035] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
|
||||
if (!mysqli_stmt_execute($stmt))
|
||||
printf("[036] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
|
||||
$id = NULL;
|
||||
$label = NULL;
|
||||
if (true !== ($tmp = mysqli_stmt_bind_result($stmt, $id, $label)))
|
||||
printf("[035] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
|
||||
printf("[037] Expecting boolean/true, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
|
||||
|
||||
if (!is_object($tmp = $result = mysqli_stmt_get_result($stmt)))
|
||||
printf("[036] Expecting array, got %s/%s, [%d] %s\n",
|
||||
printf("[038] Expecting array, got %s/%s, [%d] %s\n",
|
||||
gettype($tmp), var_export($tmp, 1),
|
||||
mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
|
||||
if (false !== ($tmp = mysqli_stmt_fetch($stmt)))
|
||||
printf("[037] Expecting boolean/false, got %s/%s, [%d] %s\n",
|
||||
printf("[039] Expecting boolean/false, got %s/%s, [%d] %s\n",
|
||||
gettype($tmp), $tmp, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
|
||||
printf("[038] [%d] [%s]\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
printf("[039] [%d] [%s]\n", mysqli_errno($link), mysqli_error($link));
|
||||
printf("[040] [%d] [%s]\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt));
|
||||
printf("[041] [%d] [%s]\n", mysqli_errno($link), mysqli_error($link));
|
||||
while ($row = mysqli_fetch_assoc($result)) {
|
||||
var_dump($row);
|
||||
}
|
||||
mysqli_free_result($result);
|
||||
|
||||
if (!mysqli_kill($link, mysqli_thread_id($link)))
|
||||
printf("[040] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
if (!mysqli_kill($link, mysqli_thread_id($link)))
|
||||
printf("[042] [%d] %s\n", mysqli_errno($link), mysqli_error($link));
|
||||
|
||||
if (false !== ($tmp = mysqli_stmt_get_result($stmt)))
|
||||
printf("[041] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
|
||||
if (false !== ($tmp = mysqli_stmt_get_result($stmt)))
|
||||
printf("[043] Expecting false, got %s/%s\n", gettype($tmp), var_export($tmp, 1));
|
||||
|
||||
mysqli_stmt_close($stmt);
|
||||
mysqli_stmt_close($stmt);
|
||||
|
||||
try {
|
||||
try {
|
||||
mysqli_stmt_fetch($stmt);
|
||||
} catch (Error $exception) {
|
||||
echo $exception->getMessage() . "\n";
|
||||
echo $exception->getMessage(), "\n";
|
||||
}
|
||||
|
||||
mysqli_close($link);
|
||||
mysqli_close($link);
|
||||
|
||||
print "done!";
|
||||
print "done!";
|
||||
?>
|
||||
--CLEAN--
|
||||
<?php
|
||||
|
@ -165,8 +196,10 @@ if (!function_exists('mysqli_stmt_get_result'))
|
|||
mysqli_stmt object is not fully initialized
|
||||
mysqli_stmt object is not fully initialized
|
||||
mysqli_stmt object is not fully initialized
|
||||
[038] [2014] [Commands out of sync; you can't run this command now]
|
||||
[039] [0] []
|
||||
mysqli_stmt_get_result() cannot be used with cursors
|
||||
get_result() cannot be used with cursors
|
||||
[040] [2014] [Commands out of sync; you can't run this command now]
|
||||
[041] [0] []
|
||||
array(2) {
|
||||
["id"]=>
|
||||
int(1)
|
||||
|
|
|
@ -151,13 +151,19 @@ MYSQLND_METHOD(mysqlnd_stmt, get_result)(MYSQLND_STMT * const s)
|
|||
}
|
||||
|
||||
if (stmt->cursor_exists) {
|
||||
/* Silently convert buffered to unbuffered, for now */
|
||||
DBG_RETURN(s->m->use_result(s));
|
||||
/* Prepared statement cursors are not supported as of yet */
|
||||
char * msg;
|
||||
mnd_sprintf(&msg, 0, "%s() cannot be used with cursors", get_active_function_name());
|
||||
SET_CLIENT_ERROR(stmt->error_info, CR_NOT_IMPLEMENTED, UNKNOWN_SQLSTATE, msg);
|
||||
if (msg) {
|
||||
mnd_sprintf_free(msg);
|
||||
}
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
|
||||
/* Nothing to store for UPSERT/LOAD DATA*/
|
||||
if (GET_CONNECTION_STATE(&conn->state) != CONN_FETCHING_DATA || stmt->state != MYSQLND_STMT_WAITING_USE_OR_STORE) {
|
||||
SET_CLIENT_ERROR(conn->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
|
||||
SET_CLIENT_ERROR(stmt->error_info, CR_COMMANDS_OUT_OF_SYNC, UNKNOWN_SQLSTATE, mysqlnd_out_of_sync);
|
||||
DBG_RETURN(NULL);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue