summaryrefslogtreecommitdiff
path: root/mysys/charset.c
diff options
context:
space:
mode:
authorGeorgi Kodinov <Georgi.Kodinov@Oracle.com>2011-02-10 09:34:22 +0200
committerGeorgi Kodinov <Georgi.Kodinov@Oracle.com>2011-02-10 09:34:22 +0200
commitb2b69699ef0b222b53f79a22a17d5d4a06c97663 (patch)
tree1906695b4daec01353d8e92d1cadc6f4e7cfc789 /mysys/charset.c
parent7d88b552e2cceddc0b86dff69a12528481e9be1d (diff)
downloadmariadb-git-b2b69699ef0b222b53f79a22a17d5d4a06c97663.tar.gz
Bug #59884: setting charset to 2048 crashes
The retrieval of a charset by number was not doing bounds checking before accessing the internal character sets array. Added checks for valid charset number. Added asserts for valid charset number to some of the internal functions. Removed one superfluous check for charset_number 0 (since the all_charsets_array[0] is set to 0 anyway) for uniformity. Test suite added.
Diffstat (limited to 'mysys/charset.c')
-rw-r--r--mysys/charset.c20
1 files changed, 13 insertions, 7 deletions
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);