diff options
author | unknown <bar@mysql.com> | 2007-03-27 12:20:20 +0500 |
---|---|---|
committer | unknown <bar@mysql.com> | 2007-03-27 12:20:20 +0500 |
commit | 916245f9c41c3f6170e384ed6d9241ed79ca781e (patch) | |
tree | dcc136c3c9616a49226c3f72b194cbcb976c383c /strings | |
parent | 685d21b72f201a2eb16718e73c76e62ee708458d (diff) | |
download | mariadb-git-916245f9c41c3f6170e384ed6d9241ed79ca781e.tar.gz |
Bug#27079 Crash while grouping empty ucs2 strings
Problem: GROUP BY on empty ucs2 strings crashed server.
Reason: sometimes mi_unique_hash() is executed with
ptr=null and length=0, which means "empty string".
The branch of code handling UCS2 character set
was not safe against ptr=null and fell into and
endless loop even if length=0 because of poiter
arithmetic overflow.
Fix: adding special check for length=0 to avoid pointer arithmetic
overflow.
mysql-test/r/ctype_uca.result:
Adding test case
mysql-test/t/ctype_uca.test:
Adding test case
strings/ctype-uca.c:
Fix my_uca_scanner_init_ucs2 to be safe against
strings with length=0 and ptr=0.
Diffstat (limited to 'strings')
-rw-r--r-- | strings/ctype-uca.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/strings/ctype-uca.c b/strings/ctype-uca.c index 1292d7f5ede..3aad36f858c 100644 --- a/strings/ctype-uca.c +++ b/strings/ctype-uca.c @@ -6744,7 +6744,7 @@ typedef struct my_uca_scanner_handler_st int (*next)(my_uca_scanner *scanner); } my_uca_scanner_handler; -static uint16 nochar[]= {0}; +static uint16 nochar[]= {0,0}; #ifdef HAVE_CHARSET_ucs2 @@ -6769,13 +6769,33 @@ static void my_uca_scanner_init_ucs2(my_uca_scanner *scanner, CHARSET_INFO *cs __attribute__((unused)), const uchar *str, uint length) { - /* Note, no needs to initialize scanner->wbeg */ - scanner->sbeg= str; - scanner->send= str + length - 2; scanner->wbeg= nochar; - scanner->uca_length= cs->sort_order; - scanner->uca_weight= cs->sort_order_big; - scanner->contractions= cs->contractions; + if (length) + { + scanner->sbeg= str; + scanner->send= str + length - 2; + scanner->uca_length= cs->sort_order; + scanner->uca_weight= cs->sort_order_big; + scanner->contractions= cs->contractions; + } + else + { + /* + Sometimes this function is called with + str=NULL and length=0, which should be + considered as an empty string. + + The above initialization is unsafe for such cases, + because scanner->send is initialized to (NULL-2), which is 0xFFFFFFFE. + Then we fall into an endless loop in my_uca_scanner_next_ucs2(). + + Do special initialization for the case when length=0. + Initialize scanner->sbeg to an address greater than scanner->send. + Next call of my_uca_scanner_next_ucs2() will correctly return with -1. + */ + scanner->sbeg= (uchar*) &nochar[1]; + scanner->send= (uchar*) &nochar[0]; + } } |