diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index ee180169916..5d6caf21182 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -1732,3 +1732,25 @@ set @@session.autocommit=t1_min(), @@session.autocommit=t1_max(), drop table t1; drop function t1_min; drop function t1_max; +# +# Bug #59884: setting charset to 2048 crashes +# +set session character_set_results = 2048; +ERROR 42000: Unknown character set: '2048' +set session character_set_client=2048; +ERROR 42000: Unknown character set: '2048' +set session character_set_connection=2048; +ERROR 42000: Unknown character set: '2048' +set session character_set_server=2048; +ERROR 42000: Unknown character set: '2048' +set session collation_server=2048; +ERROR HY000: Unknown collation: '2048' +set session character_set_filesystem=2048; +ERROR 42000: Unknown character set: '2048' +set session character_set_database=2048; +ERROR 42000: Unknown character set: '2048' +set session collation_connection=2048; +ERROR HY000: Unknown collation: '2048' +set session collation_database=2048; +ERROR HY000: Unknown collation: '2048' +End of 5.5 tests diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index b766c1c7dc6..2b20bbdc13b 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -1476,3 +1476,29 @@ drop function t1_max; ########################################################################### + + +--echo # +--echo # Bug #59884: setting charset to 2048 crashes +--echo # + +--error ER_UNKNOWN_CHARACTER_SET +set session character_set_results = 2048; +--error ER_UNKNOWN_CHARACTER_SET +set session character_set_client=2048; +--error ER_UNKNOWN_CHARACTER_SET +set session character_set_connection=2048; +--error ER_UNKNOWN_CHARACTER_SET +set session character_set_server=2048; +--error ER_UNKNOWN_COLLATION +set session collation_server=2048; +--error ER_UNKNOWN_CHARACTER_SET +set session character_set_filesystem=2048; +--error ER_UNKNOWN_CHARACTER_SET +set session character_set_database=2048; +--error ER_UNKNOWN_COLLATION +set session collation_connection=2048; +--error ER_UNKNOWN_COLLATION +set session collation_database=2048; + +--echo End of 5.5 tests diff --git a/mysys/charset.c b/mysys/charset.c index 167d6b8ff6e..c2c46ba3fb4 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -419,6 +419,7 @@ CHARSET_INFO *default_charset_info = &my_charset_latin1; void add_compiled_collation(CHARSET_INFO *cs) { + DBUG_ASSERT(cs->number < array_elements(all_charsets)); all_charsets[cs->number]= cs; cs->state|= MY_CS_AVAILABLE; } @@ -529,14 +530,17 @@ uint get_charset_number(const char *charset_name, uint cs_flags) const char *get_charset_name(uint charset_number) { - CHARSET_INFO *cs; my_pthread_once(&charsets_initialized, init_available_charsets); - cs=all_charsets[charset_number]; - if (cs && (cs->number == charset_number) && cs->name ) - return (char*) cs->name; + if (charset_number < array_elements(all_charsets)) + { + CHARSET_INFO *cs= all_charsets[charset_number]; + + if (cs && (cs->number == charset_number) && cs->name) + return (char*) cs->name; + } - return (char*) "?"; /* this mimics find_type() */ + return "?"; /* this mimics find_type() */ } @@ -545,6 +549,8 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags) char buf[FN_REFLEN]; CHARSET_INFO *cs; + DBUG_ASSERT(cs_number < array_elements(all_charsets)); + if ((cs= all_charsets[cs_number])) { if (cs->state & MY_CS_READY) /* if CS is already initialized */ @@ -589,8 +595,8 @@ CHARSET_INFO *get_charset(uint cs_number, myf flags) return default_charset_info; my_pthread_once(&charsets_initialized, init_available_charsets); - - if (!cs_number || cs_number > array_elements(all_charsets)) + + if (cs_number >= array_elements(all_charsets)) return NULL; cs=get_internal_charset(cs_number, flags);