summaryrefslogtreecommitdiff
path: root/strings
diff options
context:
space:
mode:
authorunknown <bar@mysql.com>2007-03-27 12:20:20 +0500
committerunknown <bar@mysql.com>2007-03-27 12:20:20 +0500
commit916245f9c41c3f6170e384ed6d9241ed79ca781e (patch)
treedcc136c3c9616a49226c3f72b194cbcb976c383c /strings
parent685d21b72f201a2eb16718e73c76e62ee708458d (diff)
downloadmariadb-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.c34
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];
+ }
}