| Bug #42276 | mysql_stmt_bind_result should be not assert with bad MYSQL_BIND | ||
|---|---|---|---|
| Submitted: | 22 Jan 2009 19:22 | Modified: | 5 Nov 2009 0:28 |
| Reporter: | Jeremy Cole (Basic Quality Contributor) (OCA) | Email Updates: | |
| Status: | Verified | Impact on me: | |
| Category: | MySQL Server: C API (client library) | Severity: | S3 (Non-critical) |
| Version: | 5.0.75, 4.1, 5.0, 5.1, 6.0 bzr | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | assert, C API, mysql_bind, mysql_stmt_bind_result, prepared statement, qc | ||
[22 Jan 2009 21:01]
Sveta Smirnova
Thank you for the report. Verified as described.
[22 Jan 2009 21:05]
Sveta Smirnova
Test used to verify:
#include "mysql.h"
#include <stdio.h>
#include <strings.h>
int main()
{
MYSQL *mysql;
char out[10];
int len;
int OK;
char *query;
MYSQL_ROW row;
MYSQL_RES *result;
MYSQL_STMT *stmt;
MYSQL_BIND bind[1];
mysql= mysql_init(NULL);
mysql= mysql_real_connect(mysql, "127.0.0.1", "root", "", "test", 4040, NULL, 0);
query = "select 'foo'";
stmt = mysql_stmt_init(mysql);
OK = mysql_stmt_prepare(stmt, query, strlen(query));
OK = mysql_stmt_execute(stmt);
memset(bind, 0, sizeof(bind));
bind[0].buffer_type= MYSQL_TYPE_STRING;
bind[0].buffer= (void*) "some";
bind[0].is_null= 0;
bind[0].length= 0;
OK = mysql_stmt_bind_result(stmt, bind);
mysql_stmt_close(stmt);
mysql_close(mysql);
return 0;
}
[4 Nov 2009 19:03]
Byron Campen
I am not convinced that this is an error at all; setting a buffer_length to 0 will cause MYSQL_DATA_TRUNCATED to be returned when mysql_stmt_fetch is called, allowing the caller to determine the needed buffer length. (ie; this can be used as a "peek" operation to determine how large a buffer to create)
[5 Nov 2009 0:28]
Jeremy Cole
Hi Byron, The point is that a reasonable error is NOT returned when using a debug library, instead the library asserts, which means that the user's program loses control. Regards, Jeremy

Description: The MySQL C API behaves quite poorly with badly behaved prepared statement code. Isn't it possible to issue an error message rather than a DBUG_ASSERT in a debug library (or ignoring the condition in a release build)? From libmysql.c, in setup_one_fetch_function as called by mysql_stmt_bind_result: case MYSQL_TYPE_TINY_BLOB: case MYSQL_TYPE_MEDIUM_BLOB: case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_BLOB: case MYSQL_TYPE_BIT: DBUG_ASSERT(param->buffer_length != 0); param->fetch_result= fetch_result_bin; break; case MYSQL_TYPE_VAR_STRING: case MYSQL_TYPE_STRING: case MYSQL_TYPE_DECIMAL: case MYSQL_TYPE_NEWDECIMAL: case MYSQL_TYPE_NEWDATE: DBUG_ASSERT(param->buffer_length != 0); param->fetch_result= fetch_result_str; break; How to repeat: Pass a 0 as param->buffer_length for one of the MYSQL_TYPE_* fields as above. Suggested fix: Return some reasonable error/failure case for all errors in the C API. Why should we ever assert() or ignore an error condition *deep* inside someone else's code?