diff --git a/libmariadb/mariadb_lib.c b/libmariadb/mariadb_lib.c index ff47829c..49eff309 100644 --- a/libmariadb/mariadb_lib.c +++ b/libmariadb/mariadb_lib.c @@ -1967,84 +1967,67 @@ mysql_send_query(MYSQL* mysql, const char* query, unsigned long length) return ma_simple_command(mysql, COM_QUERY, query, length, 1,0); } -int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length) +int mthd_my_read_query_result(MYSQL *mysql) { - size_t item_len; - mysql->affected_rows= net_field_length_ll(&pos); - mysql->insert_id= net_field_length_ll(&pos); - mysql->server_status=uint2korr(pos); - pos+=2; - mysql->warning_count=uint2korr(pos); - pos+=2; - if (pos < mysql->net.read_pos+length) + uchar *pos; + ulong field_count; + MYSQL_DATA *fields; + ulong length; + + if (!mysql || (length = ma_net_safe_read(mysql)) == packet_error) { - if ((item_len= net_field_length(&pos))) - mysql->info=(char*) pos; - - /* check if server supports session tracking */ - if (mysql->server_capabilities & CLIENT_SESSION_TRACKING) + return(1); + } + free_old_query(mysql); /* Free old result */ +get_info: + pos=(uchar*) mysql->net.read_pos; + if ((field_count= net_field_length(&pos)) == 0) + { + size_t item_len; + mysql->affected_rows= net_field_length_ll(&pos); + mysql->insert_id= net_field_length_ll(&pos); + mysql->server_status=uint2korr(pos); + pos+=2; + mysql->warning_count=uint2korr(pos); + pos+=2; + if (pos < mysql->net.read_pos+length) { - ma_clear_session_state(mysql); - pos+= item_len; + if ((item_len= net_field_length(&pos))) + 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; - if (pos < mysql->net.read_pos + length) + ma_clear_session_state(mysql); + pos+= item_len; + + if (mysql->server_status & SERVER_SESSION_STATE_CHANGED) { - LIST *session_item; - MYSQL_LEX_STRING *str= NULL; - 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) + int i; + if (pos < mysql->net.read_pos + length) { - size_t plen; - char *data; - old_pos= pos; - si_type= (enum enum_session_state_type)net_field_length(&pos); - switch(si_type) { - 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, - 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); + LIST *session_item; + MYSQL_LEX_STRING *str= NULL; + enum enum_session_state_type si_type; + uchar *old_pos= pos; + size_t item_len= net_field_length(&pos); /* length for all items */ - /* in case schema has changed, we have to update mysql->db */ - if (si_type == SESSION_TRACK_SCHEMA) - { - free(mysql->db); - mysql->db= malloc(plen + 1); - memcpy(mysql->db, str->str, plen); - mysql->db[plen]= 0; - } - 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; + /* 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; + char *data; + old_pos= pos; + si_type= (enum enum_session_state_type)net_field_length(&pos); + switch(si_type) { + 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), @@ -2061,54 +2044,68 @@ int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length) 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) + + /* in case schema has changed, we have to update mysql->db */ + if (si_type == SESSION_TRACK_SCHEMA) { - 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; + free(mysql->db); + mysql->db= malloc(plen + 1); + memcpy(mysql->db, str->str, plen); + mysql->db[plen]= 0; } + 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; - default: - /* not supported yet */ - plen= net_field_length(&pos); - pos+= plen; - break; + item_len-= (pos - old_pos); } - item_len-= (pos - old_pos); } - } - 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].current= mysql->extension->session_state[i].list; + 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].current= mysql->extension->session_state[i].list; + } } } } + return(0); } - return(0); -} - -int mthd_my_read_query_result(MYSQL *mysql) -{ - uchar *pos; - ulong field_count; - MYSQL_DATA *fields; - ulong length; - - if (!mysql || (length = ma_net_safe_read(mysql)) == packet_error) - { - return(1); - } - free_old_query(mysql); /* Free old result */ -get_info: - pos=(uchar*) mysql->net.read_pos; - if ((field_count= net_field_length(&pos)) == 0) - return ma_read_ok_packet(mysql, pos, length); if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */ { int error=mysql_handle_local_infile(mysql, (char *)pos); diff --git a/plugins/auth/my_auth.c b/plugins/auth/my_auth.c index aeea9d00..8db6e04e 100644 --- a/plugins/auth/my_auth.c +++ b/plugins/auth/my_auth.c @@ -10,7 +10,6 @@ static int client_mpvio_write_packet(struct st_plugin_vio*, const uchar*, size_t static int native_password_auth_client(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql); extern void read_user_name(char *name); extern char *ma_send_connect_attr(MYSQL *mysql, unsigned char *buffer); -extern int ma_read_ok_packet(MYSQL *mysql, uchar *pos, ulong length); typedef struct { int (*read_packet)(struct st_plugin_vio *vio, uchar **buf); @@ -578,6 +577,7 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len, errno); return 1; } + if (mysql->net.read_pos[0] == 254) { /* The server asked to use a different authentication plugin */ @@ -632,8 +632,6 @@ int run_plugin_auth(MYSQL *mysql, char *data, uint data_len, net->read_pos[0] should always be 0 here if the server implements the protocol correctly */ - if (mysql->net.read_pos[0] == 0) - return ma_read_ok_packet(mysql, mysql->net.read_pos + 1, pkt_length); - return 1; + return mysql->net.read_pos[0] != 0; } diff --git a/unittest/libmariadb/connection.c b/unittest/libmariadb/connection.c index c3f444a0..a2108270 100644 --- a/unittest/libmariadb/connection.c +++ b/unittest/libmariadb/connection.c @@ -1486,45 +1486,7 @@ static int test_conc327(MYSQL *unused __attribute__((unused))) } #endif -static int test_conc332(MYSQL *unused __attribute__((unused))) -{ - int rc; - MYSQL *mysql= mysql_init(NULL); - int server_status1, server_status2; - - my_test_connect(mysql, hostname, username, password, schema, - port, socketname, 0); - - FAIL_IF(mysql_errno(mysql), "Error during connect"); - - mariadb_get_infov(mysql, MARIADB_CONNECTION_SERVER_STATUS, &server_status1); - diag("server_status: %d", server_status1); - - if (server_status1 & SERVER_STATUS_AUTOCOMMIT) - rc= mysql_query(mysql, "SET autocommit= 0"); - else - rc= mysql_query(mysql, "SET autocommit= 1"); - check_mysql_rc(rc, mysql); - mariadb_get_infov(mysql, MARIADB_CONNECTION_SERVER_STATUS, &server_status2); - diag("server_status after changing autocommit: %d", server_status2); - - rc= mysql_change_user(mysql, username, password, schema); - check_mysql_rc(rc, mysql); - - mariadb_get_infov(mysql, MARIADB_CONNECTION_SERVER_STATUS, &server_status2); - diag("server_status after mysql_change_user: %d", server_status2); - if (server_status1 != server_status2) - { - diag("Expected server_status %d instead of %d", server_status1, server_status2); - mysql_close(mysql); - return FAIL; - } - mysql_close(mysql); - return OK; -} - struct my_tests_st my_tests[] = { - {"test_conc332", test_conc332, TEST_CONNECTION_NONE, 0, NULL, NULL}, #ifndef WIN32 {"test_conc327", test_conc327, TEST_CONNECTION_DEFAULT, 0, NULL, NULL}, {"test_conc317", test_conc317, TEST_CONNECTION_DEFAULT, 0, NULL, NULL},