summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/mysql_com.h3
-rw-r--r--mysql-test/r/ctype_utf8.result12
-rw-r--r--mysql-test/t/ctype_utf8.test16
-rw-r--r--sql-common/client.c6
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/table.cc6
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);
}