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

few bugs in the tracker support

* ma_multi_malloc wanted uint for size arguments, not size_t
* ma_multi_malloc needs NULL pointer at the end. Simple 0
  is not always the right size
* don't look for tracker info, if the packet does not even
  has the info_len field
This commit is contained in:
Sergei Golubchik
2016-09-21 17:35:54 +02:00
parent f968c04037
commit 4ff192bb40
2 changed files with 88 additions and 85 deletions

View File

@@ -166,13 +166,13 @@ void *ma_multi_malloc(myf myFlags, ...)
{ {
va_list args; va_list args;
char **ptr,*start,*res; char **ptr,*start,*res;
uint tot_length,length; size_t tot_length,length;
va_start(args,myFlags); va_start(args,myFlags);
tot_length=0; tot_length=0;
while ((ptr=va_arg(args, char **))) while ((ptr=va_arg(args, char **)))
{ {
length=va_arg(args,uint); length=va_arg(args, size_t);
tot_length+=ALIGN_SIZE(length); tot_length+=ALIGN_SIZE(length);
} }
va_end(args); va_end(args);
@@ -185,7 +185,7 @@ void *ma_multi_malloc(myf myFlags, ...)
while ((ptr=va_arg(args, char **))) while ((ptr=va_arg(args, char **)))
{ {
*ptr=res; *ptr=res;
length=va_arg(args,uint); length=va_arg(args,size_t);
res+=ALIGN_SIZE(length); res+=ALIGN_SIZE(length);
} }
va_end(args); va_end(args);

View File

@@ -1929,79 +1929,50 @@ get_info:
pos+=2; pos+=2;
mysql->warning_count=uint2korr(pos); mysql->warning_count=uint2korr(pos);
pos+=2; pos+=2;
if (pos < mysql->net.read_pos+length && (item_len= net_field_length(&pos))) if (pos < mysql->net.read_pos+length)
mysql->info=(char*) pos;
/* check if server supports session tracking */
if (mysql->server_capabilities & CLIENT_SESSION_TRACKING)
{ {
ma_clear_session_state(mysql); if ((item_len= net_field_length(&pos)))
pos+= item_len; mysql->info=(char*) pos;
if (mysql->server_status & SERVER_SESSION_STATE_CHANGED) /* check if server supports session tracking */
if (mysql->server_capabilities & CLIENT_SESSION_TRACKING)
{ {
int i; ma_clear_session_state(mysql);
if (pos < mysql->net.read_pos + length) pos+= item_len;
if (mysql->server_status & SERVER_SESSION_STATE_CHANGED)
{ {
LIST *session_item; int i;
MYSQL_LEX_STRING *str= NULL; if (pos < mysql->net.read_pos + length)
enum enum_session_state_type si_type;
uchar *old_pos= pos;
size_t item_len= net_field_length(&pos); /* length for all items */
/* length was already set, so make sure that info will be zero terminated */
if (mysql->info)
*old_pos= 0;
while (item_len > 0)
{ {
size_t plen; LIST *session_item;
char *data; MYSQL_LEX_STRING *str= NULL;
old_pos= pos; enum enum_session_state_type si_type;
si_type= (enum enum_session_state_type)net_field_length(&pos); uchar *old_pos= pos;
switch(si_type) { size_t item_len= net_field_length(&pos); /* length for all items */
case SESSION_TRACK_SCHEMA:
case SESSION_TRACK_STATE_CHANGE:
case SESSION_TRACK_TRANSACTION_CHARACTERISTICS:
case SESSION_TRACK_SYSTEM_VARIABLES:
net_field_length(&pos); /* ignore total length, item length will follow next */
plen= net_field_length(&pos);
if (!ma_multi_malloc(0,
&session_item, sizeof(LIST),
&str, sizeof(MYSQL_LEX_STRING),
&data, plen,
0))
{
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return -1;
}
str->length= plen;
str->str= data;
memcpy(str->str, (char *)pos, plen);
pos+= plen;
session_item->data= str;
mysql->extension->session_state[si_type].list= list_add(mysql->extension->session_state[si_type].list, session_item);
/* in case schema has changed, we have to update mysql->db */ /* length was already set, so make sure that info will be zero terminated */
if (si_type == SESSION_TRACK_SCHEMA) if (mysql->info)
{ *old_pos= 0;
free(mysql->db);
mysql->db= malloc(plen + 1); while (item_len > 0)
memcpy(mysql->db, str->str, plen); {
mysql->db[plen]= 0; size_t plen;
} char *data;
else if (si_type == SESSION_TRACK_SYSTEM_VARIABLES) old_pos= pos;
{ si_type= (enum enum_session_state_type)net_field_length(&pos);
my_bool set_charset= 0; switch(si_type) {
/* make sure that we update charset in case it has changed */ case SESSION_TRACK_SCHEMA:
if (!strncmp(str->str, "character_set_client", str->length)) case SESSION_TRACK_STATE_CHANGE:
set_charset= 1; case SESSION_TRACK_TRANSACTION_CHARACTERISTICS:
case SESSION_TRACK_SYSTEM_VARIABLES:
net_field_length(&pos); /* ignore total length, item length will follow next */
plen= net_field_length(&pos); plen= net_field_length(&pos);
if (!ma_multi_malloc(0, if (!ma_multi_malloc(0,
&session_item, sizeof(LIST), &session_item, sizeof(LIST),
&str, sizeof(MYSQL_LEX_STRING), &str, sizeof(MYSQL_LEX_STRING),
&data, plen, &data, plen,
0)) NULL))
{ {
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0); SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return -1; return -1;
@@ -2012,31 +1983,63 @@ get_info:
pos+= plen; pos+= plen;
session_item->data= str; session_item->data= str;
mysql->extension->session_state[si_type].list= list_add(mysql->extension->session_state[si_type].list, session_item); mysql->extension->session_state[si_type].list= list_add(mysql->extension->session_state[si_type].list, session_item);
if (set_charset &&
strncmp(mysql->charset->csname, str->str, str->length) != 0) /* in case schema has changed, we have to update mysql->db */
if (si_type == SESSION_TRACK_SCHEMA)
{ {
char cs_name[64]; free(mysql->db);
MARIADB_CHARSET_INFO *cs_info; mysql->db= malloc(plen + 1);
memcpy(cs_name, str->str, str->length); memcpy(mysql->db, str->str, plen);
cs_name[str->length]= 0; mysql->db[plen]= 0;
if ((cs_info = (MARIADB_CHARSET_INFO *)mysql_find_charset_name(cs_name)))
mysql->charset= cs_info;
} }
else if (si_type == SESSION_TRACK_SYSTEM_VARIABLES)
{
my_bool set_charset= 0;
/* make sure that we update charset in case it has changed */
if (!strncmp(str->str, "character_set_client", str->length))
set_charset= 1;
plen= net_field_length(&pos);
if (!ma_multi_malloc(0,
&session_item, sizeof(LIST),
&str, sizeof(MYSQL_LEX_STRING),
&data, plen,
NULL))
{
SET_CLIENT_ERROR(mysql, CR_OUT_OF_MEMORY, SQLSTATE_UNKNOWN, 0);
return -1;
}
str->length= plen;
str->str= data;
memcpy(str->str, (char *)pos, plen);
pos+= plen;
session_item->data= str;
mysql->extension->session_state[si_type].list= list_add(mysql->extension->session_state[si_type].list, session_item);
if (set_charset &&
strncmp(mysql->charset->csname, str->str, str->length) != 0)
{
char cs_name[64];
MARIADB_CHARSET_INFO *cs_info;
memcpy(cs_name, str->str, str->length);
cs_name[str->length]= 0;
if ((cs_info = (MARIADB_CHARSET_INFO *)mysql_find_charset_name(cs_name)))
mysql->charset= cs_info;
}
}
break;
default:
/* not supported yet */
plen= net_field_length(&pos);
pos+= plen;
break;
} }
break; item_len-= (pos - old_pos);
default:
/* not supported yet */
plen= net_field_length(&pos);
pos+= plen;
break;
} }
item_len-= (pos - old_pos);
} }
} for (i= SESSION_TRACK_BEGIN; i <= SESSION_TRACK_END; i++)
for (i= SESSION_TRACK_BEGIN; i <= SESSION_TRACK_END; i++) {
{ mysql->extension->session_state[i].list= list_reverse(mysql->extension->session_state[i].list);
mysql->extension->session_state[i].list= list_reverse(mysql->extension->session_state[i].list); mysql->extension->session_state[i].current= mysql->extension->session_state[i].list;
mysql->extension->session_state[i].current= mysql->extension->session_state[i].list; }
} }
} }
} }