diff options
-rw-r--r-- | include/mysql_com.h | 3 | ||||
-rw-r--r-- | mysql-test/r/ctype_utf8.result | 12 | ||||
-rw-r--r-- | mysql-test/t/ctype_utf8.test | 16 | ||||
-rw-r--r-- | sql-common/client.c | 6 | ||||
-rw-r--r-- | sql/sql_acl.cc | 6 | ||||
-rw-r--r-- | sql/sql_parse.cc | 4 | ||||
-rw-r--r-- | sql/table.cc | 6 |
7 files changed, 45 insertions, 8 deletions
diff --git a/include/mysql_com.h b/include/mysql_com.h index 56c7f7d2ab5..28c3f86701f 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -26,6 +26,9 @@ #define USERNAME_LENGTH 16 #define SERVER_VERSION_LENGTH 60 #define SQLSTATE_LENGTH 5 +#define SYSTEM_CHARSET_MBMAXLEN 3 +#define NAME_BYTE_LEN NAME_LEN*SYSTEM_CHARSET_MBMAXLEN +#define USERNAME_BYTE_LENGTH USERNAME_LENGTH*SYSTEM_CHARSET_MBMAXLEN #define LOCAL_HOST "localhost" #define LOCAL_HOST_NAMEDPIPE "." diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 5a175ba1713..941b834a733 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1340,3 +1340,15 @@ select a from t1 group by a; a e drop table t1; +set names utf8; +grant select on test.* to юзер_юзер@localhost; +user() +юзер_юзер@localhost +revoke all on test.* from юзер_юзер@localhost; +drop user юзер_юзер@localhost; +create database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; +use имя_базы_в_кодировке_утф8_длиной_больше_чем_45; +select database(); +database() +имя_базы_в_кодировке_утф8_длиной_больше_чем_45 +drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index eb395680cc9..7272cb79089 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1072,4 +1072,20 @@ explain select a from t1 group by a; select a from t1 group by a; drop table t1; +# +# Bug#20393: User name truncation in mysql client +# Bug#21432: Database/Table name limited to 64 bytes, not chars, problems with multi-byte +# +set names utf8; +#create user юзер_юзер@localhost; +grant select on test.* to юзер_юзер@localhost; +--exec $MYSQL --default-character-set=utf8 --user=юзер_юзер -e "select user()" +revoke all on test.* from юзер_юзер@localhost; +drop user юзер_юзер@localhost; + +create database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; +use имя_базы_в_кодировке_утф8_длиной_больше_чем_45; +select database(); +drop database имя_базы_в_кодировке_утф8_длиной_больше_чем_45; + # End of 4.1 tests diff --git a/sql-common/client.c b/sql-common/client.c index ff5f1ef150a..4d37b850bcb 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1618,7 +1618,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, const char *passwd, const char *db, uint port, const char *unix_socket,ulong client_flag) { - char buff[NAME_LEN+USERNAME_LENGTH+100]; + char buff[NAME_BYTE_LEN+USERNAME_BYTE_LENGTH+100]; char *end,*host_info; my_socket sock; in_addr_t ip_addr; @@ -2063,7 +2063,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, mysql->server_status, client_flag)); /* This needs to be changed as it's not useful with big packets */ if (user && user[0]) - strmake(end,user,USERNAME_LENGTH); /* Max user name */ + strmake(end,user,USERNAME_BYTE_LENGTH); /* Max user name */ else read_user_name((char*) end); @@ -2093,7 +2093,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, /* Add database if needed */ if (db && (mysql->server_capabilities & CLIENT_CONNECT_WITH_DB)) { - end= strmake(end, db, NAME_LEN) + 1; + end= strmake(end, db, NAME_BYTE_LEN) + 1; mysql->db= my_strdup(db,MYF(MY_WME)); db= 0; } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 0ad5432f3eb..6ede19d0e96 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2640,7 +2640,11 @@ int mysql_grant(THD *thd, const char *db, List <LEX_USER> &list, while ((Str = str_list++)) { if (Str->host.length > HOSTNAME_LENGTH || - Str->user.length > USERNAME_LENGTH) + system_charset_info->cset->charpos(system_charset_info, + Str->user.str, + Str->user.str + + Str->user.length, + USERNAME_LENGTH) < Str->user.length) { my_error(ER_GRANT_WRONG_HOST_OR_USER,MYF(0)); result= -1; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index cf1f50aed63..89ecceeb1bf 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -902,8 +902,8 @@ static int check_connection(THD *thd) char *user= end; char *passwd= strend(user)+1; char *db= passwd; - char db_buff[NAME_LEN+1]; // buffer to store db in utf8 - char user_buff[USERNAME_LENGTH+1]; // buffer to store user in utf8 + char db_buff[NAME_BYTE_LEN + 1]; // buffer to store db in utf8 + char user_buff[USERNAME_BYTE_LENGTH + 1]; // buffer to store user in utf8 uint dummy_errors; /* diff --git a/sql/table.cc b/sql/table.cc index 29e7d5ebf26..7587531b2f9 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1413,7 +1413,7 @@ char *get_field(MEM_ROOT *mem, Field *field) bool check_db_name(char *name) { - char *start=name; + uint name_length= 0; // name length in symbols /* Used to catch empty names and names with end space */ bool last_char_is_space= TRUE; @@ -1430,6 +1430,7 @@ bool check_db_name(char *name) name+system_charset_info->mbmaxlen); if (len) { + name_length++; name += len; continue; } @@ -1437,12 +1438,13 @@ bool check_db_name(char *name) #else last_char_is_space= *name==' '; #endif + name_length++; if (*name == '/' || *name == '\\' || *name == FN_LIBCHAR || *name == FN_EXTCHAR) return 1; name++; } - return last_char_is_space || (uint) (name - start) > NAME_LEN; + return (last_char_is_space || name_length > NAME_LEN); } |