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

Fix for CONC-194: (merged from connector_c_2.3)

This commit is contained in:
Georg Richter
2016-08-03 12:41:52 +02:00
parent 7b14603438
commit 4f2c9da859
2 changed files with 75 additions and 34 deletions

View File

@@ -921,10 +921,6 @@ static
void ps_fetch_bin(MYSQL_BIND *r_param, const MYSQL_FIELD *field, void ps_fetch_bin(MYSQL_BIND *r_param, const MYSQL_FIELD *field,
unsigned char **row) unsigned char **row)
{ {
ulong field_length;
size_t copylen;
/* If r_praram->buffer_type is not a binary type or binary_flag isn't set, /* If r_praram->buffer_type is not a binary type or binary_flag isn't set,
we do conversion from string */ we do conversion from string */
if (!(field->flags & BINARY_FLAG) || if (!(field->flags & BINARY_FLAG) ||
@@ -941,21 +937,32 @@ void ps_fetch_bin(MYSQL_BIND *r_param, const MYSQL_FIELD *field,
ps_fetch_string(r_param, field, row); ps_fetch_string(r_param, field, row);
return; return;
} }
field_length= net_field_length(row); else
{
copylen= MIN(field_length, r_param->buffer_length); ulong field_length= *r_param->length= net_field_length(row);
memcpy(r_param->buffer, *row, copylen); uchar *current_pos= (*row) + r_param->u.offset,
*r_param->error= copylen < field_length; *end= (*row) + field_length;
size_t copylen= 0;
if (current_pos < end)
{
copylen= end - current_pos;
if (r_param->buffer_length)
{
memcpy(r_param->buffer, current_pos, MIN(copylen, r_param->buffer_length));
if (copylen < r_param->buffer_length &&
r_param->buffer_type == MYSQL_TYPE_STRING)
((char *)r_param->buffer)[copylen]= 0;
}
}
*r_param->error= copylen > r_param->buffer_length;
/* don't count trailing zero if we fetch into string */ /* don't count trailing zero if we fetch into string */
if (r_param->buffer_type == MYSQL_TYPE_STRING && if (r_param->buffer_type == MYSQL_TYPE_STRING &&
!*r_param->error) !*r_param->error)
field_length--; field_length--;
*r_param->length= field_length;
(*row)+= field_length; (*row)+= field_length;
} }
}
/* }}} */ /* }}} */
/* {{{ _mysqlnd_init_ps_subsystem */ /* {{{ _mysqlnd_init_ps_subsystem */

View File

@@ -268,19 +268,19 @@ static int test_fetch_seek(MYSQL *mysql)
static int test_fetch_offset(MYSQL *mysql) static int test_fetch_offset(MYSQL *mysql)
{ {
MYSQL_STMT *stmt; MYSQL_STMT *stmt;
MYSQL_BIND my_bind[1]; MYSQL_BIND my_bind[2];
char data[11]; char data[11], chunk[5];
ulong length; ulong length[2];
int rc; int rc;
my_bool is_null; my_bool is_null[2];
char *query = "SELECT * FROM t1"; char *query = "SELECT * FROM t1";
rc= mysql_query(mysql, "drop table if exists t1"); rc= mysql_query(mysql, "drop table if exists t1");
check_mysql_rc(rc, mysql); check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "create table t1(a char(10))"); rc= mysql_query(mysql, "create table t1(a char(10), b mediumblob)");
check_mysql_rc(rc, mysql); check_mysql_rc(rc, mysql);
rc= mysql_query(mysql, "insert into t1 values('abcdefghij'), (null)"); rc= mysql_query(mysql, "insert into t1 values('abcdefghij', 'klmnopqrstzy'), (null, null)");
check_mysql_rc(rc, mysql); check_mysql_rc(rc, mysql);
stmt= mysql_stmt_init(mysql); stmt= mysql_stmt_init(mysql);
@@ -293,8 +293,14 @@ static int test_fetch_offset(MYSQL *mysql)
my_bind[0].buffer_type= MYSQL_TYPE_STRING; my_bind[0].buffer_type= MYSQL_TYPE_STRING;
my_bind[0].buffer= (void *)data; my_bind[0].buffer= (void *)data;
my_bind[0].buffer_length= 11; my_bind[0].buffer_length= 11;
my_bind[0].is_null= &is_null; my_bind[0].is_null= &is_null[0];
my_bind[0].length= &length; my_bind[0].length= &length[0];
my_bind[1].buffer_type= MYSQL_TYPE_MEDIUM_BLOB;
my_bind[1].buffer= NULL;
my_bind[1].buffer_length= 0;
my_bind[1].is_null= &is_null[1];
my_bind[1].length= &length[1];
rc= mysql_stmt_execute(stmt); rc= mysql_stmt_execute(stmt);
check_stmt_rc(rc,stmt); check_stmt_rc(rc,stmt);
@@ -312,32 +318,60 @@ static int test_fetch_offset(MYSQL *mysql)
check_stmt_rc(rc,stmt); check_stmt_rc(rc,stmt);
rc= mysql_stmt_fetch(stmt); rc= mysql_stmt_fetch(stmt);
check_stmt_rc(rc,stmt); FAIL_UNLESS(rc == MYSQL_DATA_TRUNCATED, "rc != MYSQL_DATA_TRUNCATED");
data[0]= '\0'; data[0]= '\0';
rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0); rc= mysql_stmt_fetch_column(stmt, &my_bind[0], 0, 0);
check_stmt_rc(rc,stmt); check_stmt_rc(rc,stmt);
FAIL_IF(!(strncmp(data, "abcd", 4) == 0 && length == 10), "Wrong value"); FAIL_IF(!(strncmp(data, "abcdefghij", 11) == 0 && length[0] == 10), "Wrong value");
FAIL_IF(my_bind[0].error_value, "No truncation, but error is set");
rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 5); rc= mysql_stmt_fetch_column(stmt, &my_bind[0], 0, 5);
check_stmt_rc(rc,stmt); check_stmt_rc(rc,stmt);
FAIL_IF(!(strncmp(data, "fg", 2) == 0 && length == 10), "Wrong value"); FAIL_IF(!(strncmp(data, "fghij", 6) == 0 && length[0] == 10), "Wrong value");
FAIL_IF(my_bind[0].error_value, "No truncation, but error is set");
rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 9); rc= mysql_stmt_fetch_column(stmt, &my_bind[0], 0, 9);
check_stmt_rc(rc,stmt); check_stmt_rc(rc,stmt);
FAIL_IF(!(strncmp(data, "j", 1) == 0 && length == 10), "Wrong value"); FAIL_IF(!(strncmp(data, "j", 2) == 0 && length[0] == 10), "Wrong value");
FAIL_IF(my_bind[0].error_value, "No truncation, but error is set");
/* Now blob field */
my_bind[1].buffer= chunk;
my_bind[1].buffer_length= sizeof(chunk);
rc= mysql_stmt_fetch_column(stmt, &my_bind[1], 1, 0);
check_stmt_rc(rc,stmt);
FAIL_IF(!(strncmp(chunk, "klmno", 5) == 0 && length[1] == 12), "Wrong value");
FAIL_IF(my_bind[1].error_value == '\0', "Truncation, but error is not set");
rc= mysql_stmt_fetch_column(stmt, &my_bind[1], 1, 5);
check_stmt_rc(rc,stmt);
FAIL_IF(!(strncmp(chunk, "pqrst", 5) == 0 && length[1] == 12), "Wrong value");
FAIL_IF(my_bind[1].error_value == '\0', "Truncation, but error is not set");
rc= mysql_stmt_fetch_column(stmt, &my_bind[1], 1, 10);
check_stmt_rc(rc,stmt);
FAIL_IF(!(strncmp(chunk, "zy", 2) == 0 && length[1] == 12), "Wrong value");
FAIL_IF(my_bind[1].error_value, "No truncation, but error is set");
rc= mysql_stmt_fetch(stmt); rc= mysql_stmt_fetch(stmt);
check_stmt_rc(rc,stmt); check_stmt_rc(rc,stmt);
is_null= 0; memset(is_null, 0, sizeof(is_null));
rc= mysql_stmt_fetch_column(stmt, my_bind, 0, 0); rc= mysql_stmt_fetch_column(stmt, &my_bind[0], 0, 0);
check_stmt_rc(rc,stmt); check_stmt_rc(rc,stmt);
FAIL_IF(is_null != 1, "Null flag not set"); FAIL_IF(is_null[0] != 1, "Null flag not set");
rc= mysql_stmt_fetch_column(stmt, &my_bind[1], 1, 0);
check_stmt_rc(rc,stmt);
FAIL_IF(is_null[1] != 1, "Null flag not set");
rc= mysql_stmt_fetch(stmt); rc= mysql_stmt_fetch(stmt);
FAIL_IF(rc != MYSQL_NO_DATA, "Expected MYSQL_NO_DATA"); FAIL_IF(rc != MYSQL_NO_DATA, "Expected MYSQL_NO_DATA");