Skip to content

Commit c0740eb

Browse files
committed
Set stmt->bind_result_done = 0 when freeing the result buffers that were bound to a statement handle
If the statement handle was previously used, and so mysql_stmt_bind_result was called, and if that result set and bind buffers were freed, MySQL still thinks the result set buffer is available and will prefetch the first result in mysql_stmt_execute. This will corrupt or crash the program. By setting bind_result_done back to 0, we make MySQL think that a result set has never been bound to this statement handle before to prevent the prefetch. Is this a MySQL bug or a problem in the workflow, i.e. should a result buffer be allocated and bound once and then never "unbound" from a statement handle?
1 parent ab39262 commit c0740eb

File tree

1 file changed

+9
-0
lines changed

1 file changed

+9
-0
lines changed

ext/mysql2/result.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,15 @@ static void rb_mysql_result_free_result(mysql2_result_wrapper * wrapper) {
9595
if (wrapper->stmt_wrapper) {
9696
mysql_stmt_free_result(wrapper->stmt_wrapper->stmt);
9797

98+
/* MySQL BUG? If the statement handle was previously used, and so
99+
* mysql_stmt_bind_result was called, and if that result set and bind buffers were freed,
100+
* MySQL still thinks the result set buffer is available and will prefetch the
101+
* first result in mysql_stmt_execute. This will corrupt or crash the program.
102+
* By setting bind_result_done back to 0, we make MySQL think that a result set
103+
* has never been bound to this statement handle before to prevent the prefetch.
104+
*/
105+
wrapper->stmt_wrapper->stmt->bind_result_done = 0;
106+
98107
if (wrapper->result_buffers) {
99108
unsigned int i;
100109
for (i = 0; i < wrapper->numberOfFields; i++) {

0 commit comments

Comments
 (0)