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_parse.cc | 4 | ||||
-rw-r--r-- | sql/table.cc | 6 |
6 files changed, 40 insertions, 7 deletions
diff --git a/include/mysql_com.h b/include/mysql_com.h index 4c7640376a6..eb534cd034d 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 /* USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index bf271437fac..f7baa8b98e5 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1340,6 +1340,18 @@ select a from t1 group by a; a e drop table t1; +set names utf8; +grant select on test.* to ム<8e>ミキミオム<80>_ム<8e>ミキミオム<80>@localhost; +user() +ム<8e>ミキミオム<80>_ム<8e>ミキミオム<80>@localhost +revoke all on test.* from ム<8e>ミキミオム<80>_ム<8e>ミキミオム<80>@localhost; +drop user ム<8e>ミキミオム<80>_ム<8e>ミキミオム<80>@localhost; +create database ミクミシム<8f>_ミアミーミキム<8b>_ミイ_ミコミセミエミクム<80>ミセミイミコミオ_ム<83>ム<82>ム<84>8_ミエミサミクミスミセミケ_ミアミセミサム<8c>ム<88>ミオ_ム<87>ミオミシ_45; +use ミクミシム<8f>_ミアミーミキム<8b>_ミイ_ミコミセミエミクム<80>ミセミイミコミオ_ム<83>ム<82>ム<84>8_ミエミサミクミスミセミケ_ミアミセミサム<8c>ム<88>ミオ_ム<87>ミオミシ_45; +select database(); +database() +ミクミシム<8f>_ミアミーミキム<8b>_ミイ_ミコミセミエミクム<80>ミセミイミコミオ_ム<83>ム<82>ム<84>8_ミエミサミクミスミセミケ_ミアミセミサム<8c>ム<88>ミオ_ム<87>ミオミシ_45 +drop database ミクミシム<8f>_ミアミーミキム<8b>_ミイ_ミコミセミエミクム<80>ミセミイミコミオ_ム<83>ム<82>ム<84>8_ミエミサミクミスミセミケ_ミアミセミサム<8c>ム<88>ミオ_ム<87>ミオミシ_45; CREATE TABLE t1(id varchar(20) NOT NULL) DEFAULT CHARSET=utf8; INSERT INTO t1 VALUES ('xxx'), ('aa'), ('yyy'), ('aa'); SELECT id FROM t1; diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 39928f18f2e..e6f939abdcd 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1069,6 +1069,22 @@ 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 cfd53fb1012..fc483e7b4c7 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1758,7 +1758,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; @@ -2217,7 +2217,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); @@ -2247,7 +2247,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_parse.cc b/sql/sql_parse.cc index 2acbf18f1e6..bb969a77d89 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1001,8 +1001,8 @@ static int check_connection(THD *thd) char *passwd= strend(user)+1; uint user_len= passwd - 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 0a95461cf06..054736401ff 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -1592,7 +1592,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; @@ -1609,6 +1609,7 @@ bool check_db_name(char *name) name+system_charset_info->mbmaxlen); if (len) { + name_length++; name += len; continue; } @@ -1616,12 +1617,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); } |