From: Alexander Barkov Date: February 18 2011 9:57am Subject: bzr push into mysql-trunk branch (alexander.barkov:3673 to 3674) List-Archive: http://lists.mysql.com/commits/131607 Message-Id: <201102180957.p1I9vKAb029996@bar.myoffice.izhnet.ru> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3674 Alexander Barkov 2011-02-18 [merge] Merging from mysql-5.5. modified: sql/set_var.cc sql/sql_acl.cc sql/sql_connect.cc sql/sql_connect.h sql/sql_parse.h tests/mysql_client_test.c 3673 Alexander Barkov 2011-02-18 [merge] Merging from 5.5. modified: mysql-test/r/ctype_cp1251.result mysql-test/t/ctype_cp1251.test sql/item_cmpfunc.cc === modified file 'sql/set_var.cc' --- a/sql/set_var.cc 2011-02-17 11:58:08 +0000 +++ b/sql/set_var.cc 2011-02-18 09:56:51 +0000 @@ -774,7 +774,7 @@ int set_var_password::update(THD *thd) int set_var_collation_client::check(THD *thd) { /* Currently, UCS-2 cannot be used as a client character set */ - if (character_set_client->mbminlen > 1) + if (!is_supported_parser_charset(character_set_client)) { my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client", character_set_client->csname); === modified file 'sql/sql_acl.cc' --- a/sql/sql_acl.cc 2011-01-24 15:05:24 +0000 +++ b/sql/sql_acl.cc 2011-02-18 09:56:51 +0000 @@ -7853,7 +7853,8 @@ public: Thd_charset_adapter(THD *thd_arg) : thd (thd_arg) {} bool init_client_charset(uint cs_number) { - thd_init_client_charset(thd, cs_number); + if (thd_init_client_charset(thd, cs_number)) + return true; thd->update_charset(); return thd->is_error(); } @@ -8983,9 +8984,8 @@ server_mpvio_initialize(THD *thd, MPVIO_ mpvio->auth_info.host_or_ip= thd->security_ctx->host_or_ip; mpvio->auth_info.host_or_ip_length= (unsigned int) strlen(thd->security_ctx->host_or_ip); - mpvio->auth_info.user_name= thd->security_ctx->user; - mpvio->auth_info.user_name_length= thd->security_ctx->user ? - (unsigned int) strlen(thd->security_ctx->user) : 0; + mpvio->auth_info.user_name= NULL; + mpvio->auth_info.user_name_length= 0; mpvio->connect_errors= connect_errors; mpvio->status= MPVIO_EXT::FAILURE; === modified file 'sql/sql_connect.cc' --- a/sql/sql_connect.cc 2010-12-15 23:10:37 +0000 +++ b/sql/sql_connect.cc 2011-02-18 09:56:51 +0000 @@ -370,8 +370,23 @@ void reset_mqh(LEX_USER *lu, bool get_th } -void thd_init_client_charset(THD *thd, uint cs_number) +/** + Set thread character set variables from the given ID + + @param thd thread handle + @param cs_number character set and collation ID + + @retval 0 OK; character_set_client, collation_connection and + character_set_results are set to the new value, + or to the default global values. + + @retval 1 error, e.g. the given ID is not supported by parser. + Corresponding SQL error is sent. +*/ + +bool thd_init_client_charset(THD *thd, uint cs_number) { + CHARSET_INFO *cs; /* Use server character set and collation if - opt_character_set_client_handshake is not set @@ -380,10 +395,10 @@ void thd_init_client_charset(THD *thd, u - client character set doesn't exists in server */ if (!opt_character_set_client_handshake || - !(thd->variables.character_set_client= get_charset(cs_number, MYF(0))) || + !(cs= get_charset(cs_number, MYF(0))) || !my_strcasecmp(&my_charset_latin1, global_system_variables.character_set_client->name, - thd->variables.character_set_client->name)) + cs->name)) { thd->variables.character_set_client= global_system_variables.character_set_client; @@ -394,10 +409,18 @@ void thd_init_client_charset(THD *thd, u } else { + if (!is_supported_parser_charset(cs)) + { + /* Disallow non-supported parser character sets: UCS2, UTF16, UTF32 */ + my_error(ER_WRONG_VALUE_FOR_VAR, MYF(0), "character_set_client", + cs->csname); + return true; + } thd->variables.character_set_results= thd->variables.collation_connection= - thd->variables.character_set_client; + thd->variables.character_set_client= cs; } + return false; } === modified file 'sql/sql_connect.h' --- a/sql/sql_connect.h 2010-10-04 15:25:10 +0000 +++ b/sql/sql_connect.h 2011-02-18 09:56:51 +0000 @@ -33,7 +33,7 @@ void reset_mqh(LEX_USER *lu, bool get_th bool check_mqh(THD *thd, uint check_command); void time_out_user_resource_limits(THD *thd, USER_CONN *uc); void decrease_user_connections(USER_CONN *uc); -void thd_init_client_charset(THD *thd, uint cs_number); +bool thd_init_client_charset(THD *thd, uint cs_number); bool setup_connection_thread_globals(THD *thd); int check_user(THD *thd, enum enum_server_command command, === modified file 'sql/sql_parse.h' --- a/sql/sql_parse.h 2010-11-15 16:43:41 +0000 +++ b/sql/sql_parse.h 2011-02-18 09:56:51 +0000 @@ -197,4 +197,10 @@ check_table_access(THD *thd, ulong requi bool check_global_access(THD *thd, ulong want_access); +inline bool is_supported_parser_charset(CHARSET_INFO *cs) +{ + return test(cs->mbminlen == 1); +} + + #endif /* SQL_PARSE_INCLUDED */ === modified file 'tests/mysql_client_test.c' --- a/tests/mysql_client_test.c 2010-12-29 00:38:59 +0000 +++ b/tests/mysql_client_test.c 2011-02-18 09:56:51 +0000 @@ -19295,6 +19295,72 @@ static void test_bug47485() /* + Bug#58036 client utf32, utf16, ucs2 should be disallowed, they crash server +*/ +static void test_bug58036() +{ + MYSQL *conn; + DBUG_ENTER("test_bug47485"); + myheader("test_bug58036"); + + /* Part1: try to connect with ucs2 client character set */ + conn= mysql_client_init(NULL); + mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2"); + if (mysql_real_connect(conn, opt_host, opt_user, + opt_password, opt_db ? opt_db : "test", + opt_port, opt_unix_socket, 0)) + { + if (!opt_silent) + printf("mysql_real_connect() succeeded (failure expected)\n"); + mysql_close(conn); + DIE(); + } + + if (!opt_silent) + printf("Got mysql_real_connect() error (expected): %s (%d)\n", + mysql_error(conn), mysql_errno(conn)); + DIE_UNLESS(mysql_errno(conn) == ER_WRONG_VALUE_FOR_VAR); + mysql_close(conn); + + + /* + Part2: + - connect with latin1 + - then change client character set to ucs2 + - then try mysql_change_user() + */ + conn= mysql_client_init(NULL); + mysql_options(conn, MYSQL_SET_CHARSET_NAME, "latin1"); + if (!mysql_real_connect(conn, opt_host, opt_user, + opt_password, opt_db ? opt_db : "test", + opt_port, opt_unix_socket, 0)) + { + if (!opt_silent) + printf("mysql_real_connect() failed: %s (%d)\n", + mysql_error(conn), mysql_errno(conn)); + mysql_close(conn); + DIE(); + } + + mysql_options(conn, MYSQL_SET_CHARSET_NAME, "ucs2"); + if (!mysql_change_user(conn, opt_user, opt_password, NULL)) + { + if (!opt_silent) + printf("mysql_change_user() succedded, error expected!"); + mysql_close(conn); + DIE(); + } + + if (!opt_silent) + printf("Got mysql_change_user() error (expected): %s (%d)\n", + mysql_error(conn), mysql_errno(conn)); + mysql_close(conn); + + DBUG_VOID_RETURN; +} + + +/* Bug#49972: Crash in prepared statements. The following case lead to a server crash: @@ -19776,6 +19842,7 @@ static struct my_tests_st my_tests[]= { { "test_bug42373", test_bug42373 }, { "test_bug54041", test_bug54041 }, { "test_bug47485", test_bug47485 }, + { "test_bug58036", test_bug58036 }, { "test_bug57058", test_bug57058 }, { 0, 0 } }; No bundle (reason: useless for push emails).