1
0
mirror of https://github.com/mariadb-corporation/mariadb-connector-c.git synced 2025-08-07 02:42:49 +03:00

Fixed memory overrun (wrong length calculation in mysql_stmt_generate_request)

Fuxed crash with mysql_send_long_data
This commit is contained in:
Georg Richter
2013-04-12 11:24:42 +02:00
parent 36ff98ddc8
commit 7a452efb58
2 changed files with 82 additions and 2 deletions

View File

@@ -504,7 +504,7 @@ unsigned char* mysql_stmt_execute_generate_request(MYSQL_STMT *stmt, size_t *req
n data from bind_buffer n data from bind_buffer
*/ */
size_t length= 9000; size_t length= 1024;
size_t free_bytes= 0; size_t free_bytes= 0;
size_t data_size= 0; size_t data_size= 0;
uint i; uint i;
@@ -513,6 +513,16 @@ unsigned char* mysql_stmt_execute_generate_request(MYSQL_STMT *stmt, size_t *req
DBUG_ENTER("mysql_stmt_execute_generate_request"); DBUG_ENTER("mysql_stmt_execute_generate_request");
/* calculate length */
for (i=0; i < stmt->param_count; i++)
{
if (!stmt->params[i].long_data_used)
length+= stmt->params[i].buffer_length ?
stmt->params[i].buffer_length + 1 :
stmt->params[i].buffer_type ?
mysql_ps_fetch_functions[MYSQL_TYPE_YEAR].pack_len + 1 : 1;
}
if (!(start= p= (uchar *)my_malloc(length, MYF(MY_WME | MY_ZEROFILL)))) if (!(start= p= (uchar *)my_malloc(length, MYF(MY_WME | MY_ZEROFILL))))
goto mem_error; goto mem_error;
@@ -573,7 +583,7 @@ unsigned char* mysql_stmt_execute_generate_request(MYSQL_STMT *stmt, size_t *req
stmt->params[i].is_null = &is_not_null; stmt->params[i].is_null = &is_not_null;
if (!stmt->params[i].length) if (!stmt->params[i].length)
stmt->params[i].length= &stmt->params[i].length_value; stmt->params[i].length= &stmt->params[i].length_value;
if (!*stmt->params[i].is_null && !stmt->params[i].long_data_used) if (!stmt->params[i].is_null && !stmt->params[i].long_data_used)
{ {
switch (stmt->params[i].buffer_type) { switch (stmt->params[i].buffer_type) {
case MYSQL_TYPE_NULL: case MYSQL_TYPE_NULL:

View File

@@ -4590,7 +4590,77 @@ static int test_new_date(MYSQL *mysql)
return OK; return OK;
} }
static int test_long_data1(MYSQL *mysql)
{
MYSQL_STMT *stmt;
int rc;
MYSQL_RES *result;
MYSQL_BIND bind[1];
char query[MAX_TEST_QUERY_LENGTH];
char *data= "12345";
rc= mysql_autocommit(mysql, TRUE);
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "DROP TABLE IF EXISTS tld");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "CREATE TABLE tld (col1 int, "
"col2 long varbinary)");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "INSERT INTO tld VALUES (1,'test')");
check_mysql_rc(rc, mysql);
strcpy(query, "UPDATE tld SET col2=? WHERE col1=1");
stmt= mysql_stmt_init(mysql);
FAIL_IF(!stmt, mysql_error(mysql));
rc= mysql_stmt_prepare(stmt, query, strlen(query));
check_stmt_rc(rc, stmt);
bind[0].buffer_type= MYSQL_TYPE_STRING;
rc= mysql_stmt_bind_param(stmt, bind);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_send_long_data(stmt, 0, data, 6);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_close(stmt);
check_stmt_rc(rc, stmt);
return OK;
}
int test_blob_9000(MYSQL *mysql)
{
MYSQL_BIND bind[1];
MYSQL_STMT *stmt;
int rc;
char buffer[9200];
char *query= "INSERT INTO tb9000 VALUES (?)";
rc= mysql_query(mysql, "DROP TABLE IF EXISTS tb9000");
check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "CREATE TABLE tb9000 (a blob)");
check_mysql_rc(rc, mysql);
stmt= mysql_stmt_init(mysql);
rc= mysql_stmt_prepare(stmt, query, strlen(query));
memset(bind, 0, sizeof(MYSQL_BIND));
memset(buffer, 'C', 9200);
bind[0].buffer= buffer;
bind[0].buffer_length= 9200;
bind[0].buffer_type= MYSQL_TYPE_STRING;
rc= mysql_stmt_bind_param(stmt, bind);
check_stmt_rc(rc, stmt);
rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc, stmt);
mysql_stmt_close(stmt);
return OK;
}
struct my_tests_st my_tests[] = { struct my_tests_st my_tests[] = {
{"test_blob_9000", test_blob_9000, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_long_data1", test_long_data1, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_prepare_insert_update", test_prepare_insert_update, TEST_CONNECTION_DEFAULT, 0, NULL , NULL}, {"test_prepare_insert_update", test_prepare_insert_update, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_prepare_simple", test_prepare_simple, TEST_CONNECTION_DEFAULT, 0, NULL , NULL}, {"test_prepare_simple", test_prepare_simple, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},
{"test_prepare_syntax", test_prepare_syntax, TEST_CONNECTION_DEFAULT, 0, NULL , NULL}, {"test_prepare_syntax", test_prepare_syntax, TEST_CONNECTION_DEFAULT, 0, NULL , NULL},