diff --git a/mysql-test/r/connect.result b/mysql-test/r/connect.result index 5e6c013bb38..381ae8b2562 100644 --- a/mysql-test/r/connect.result +++ b/mysql-test/r/connect.result @@ -215,6 +215,17 @@ SET GLOBAL event_scheduler = OFF; # -- End of Bug#35074. +# +# -- Bug#49752: 2469.126.2 unintentionally breaks authentication +# against MySQL 5.1 server +# +GRANT ALL ON test.* TO 'Azundris12345678'@'localhost' IDENTIFIED BY 'test123'; +FLUSH PRIVILEGES; +DROP USER 'Azundris12345678'@'localhost'; +FLUSH PRIVILEGES; +# +# -- End of Bug#49752 +# # ------------------------------------------------------------------ # -- End of 5.1 tests # ------------------------------------------------------------------ diff --git a/mysql-test/t/connect.test b/mysql-test/t/connect.test index 9a29e4ff861..d0b79ab6bd3 100644 --- a/mysql-test/t/connect.test +++ b/mysql-test/t/connect.test @@ -293,6 +293,34 @@ SET GLOBAL event_scheduler = OFF; --echo # -- End of Bug#35074. --echo + +########################################################################### + +--echo # +--echo # -- Bug#49752: 2469.126.2 unintentionally breaks authentication +--echo # against MySQL 5.1 server +--echo # + +GRANT ALL ON test.* TO 'Azundris12345678'@'localhost' IDENTIFIED BY 'test123'; + +FLUSH PRIVILEGES; + +--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT +connect (con1,localhost,Azundris123456789,test123,test); +disconnect con1; + +connection default; + +DROP USER 'Azundris12345678'@'localhost'; + +FLUSH PRIVILEGES; + +--echo # +--echo # -- End of Bug#49752 +--echo # + + + --echo # ------------------------------------------------------------------ --echo # -- End of 5.1 tests --echo # ------------------------------------------------------------------ diff --git a/sql/sql_connect.cc b/sql/sql_connect.cc index 28c1acc4716..9fa6966baa2 100644 --- a/sql/sql_connect.cc +++ b/sql/sql_connect.cc @@ -899,6 +899,19 @@ static int check_connection(THD *thd) user_len-= 2; } + /* + Clip username to allowed length in characters (not bytes). This is + mostly for backward compatibility. + */ + { + CHARSET_INFO *cs= system_charset_info; + int err; + + user_len= (uint) cs->cset->well_formed_len(cs, user, user + user_len, + USERNAME_CHAR_LENGTH, &err); + user[user_len]= '\0'; + } + if (thd->main_security_ctx.user) x_free(thd->main_security_ctx.user); if (!(thd->main_security_ctx.user= my_strdup(user, MYF(MY_WME)))) diff --git a/strings/CHARSET_INFO.txt b/strings/CHARSET_INFO.txt index bb8e40025c7..6f0a810be37 100644 --- a/strings/CHARSET_INFO.txt +++ b/strings/CHARSET_INFO.txt @@ -208,14 +208,11 @@ charpos() - calculates the offset of the given position in the string. Used in SQL functions LEFT(), RIGHT(), SUBSTRING(), INSERT() -well_formed_length() - - finds the length of correctly formed multi-byte beginning. - Used in INSERTs to cut a beginning of the given string - which is - a) "well formed" according to the given character set. +well_formed_len() + - returns length of a given multi-byte string in bytes + Used in INSERTs to shorten the given string so it + a) is "well formed" according to the given character set b) can fit into the given data type - Terminates the string in the good position, taking in account - multi-byte character boundaries. lengthsp() - returns the length of the given string without trailing spaces.