1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Bug#11765108 (Bug#58036) client utf32, utf16, ucs2 should be disallowed, they crash server

A separate fix for 5.1 (as 5.1 and 5.5 have seriously
differged in the related pieces of the code).
A patch for 5.5 was approved earlier.

Problem: ucs2 was correctly disallowed in "SET NAMES" only,
while mysql_real_connect() and mysql_change_user() still allowed
to use ucs2, which made server crash.

Fix: disallow ucs2 in mysql_real_connect() and mysql_change_user().

  @ sql/sql_priv.h
    - changing return type for thd_init_client_charset() to bool,
      to return errors to the caller

  @ sql/sql_var.cc
    - using new function

  @ sql/sql_connect.cc
    - thd_client_charset_init:
      in case of unsupported client character set send error and return true;
      in case of success return false
    - check_connection:
      Return error if character set initialization failed

  @ sql/sql_parse.cc
    - check charset in the very beginnig of the CMD_CHANGE_USER handling code

  @ tests/mysql_client_test.c
    - adding tests
This commit is contained in:
Alexander Barkov
2011-02-18 16:12:36 +03:00
parent f912dcd82e
commit 8a96012922
5 changed files with 117 additions and 9 deletions

View File

@ -582,8 +582,23 @@ void reset_mqh(LEX_USER *lu, bool get_them= 0)
}
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
@ -592,10 +607,10 @@ void thd_init_client_charset(THD *thd, uint cs_number)
- 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;
@ -606,10 +621,18 @@ void thd_init_client_charset(THD *thd, uint cs_number)
}
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;
}
@ -782,7 +805,8 @@ static int check_connection(THD *thd)
thd->client_capabilities|= ((ulong) uint2korr(net->read_pos+2)) << 16;
thd->max_client_packet_length= uint4korr(net->read_pos+4);
DBUG_PRINT("info", ("client_character_set: %d", (uint) net->read_pos[8]));
thd_init_client_charset(thd, (uint) net->read_pos[8]);
if (thd_init_client_charset(thd, (uint) net->read_pos[8]))
return 1;
thd->update_charset();
end= (char*) net->read_pos+32;
}