summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/ctype_utf8.result12
-rw-r--r--mysql-test/t/ctype_utf8.test9
-rw-r--r--sql/item_strfunc.cc15
3 files changed, 31 insertions, 5 deletions
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 599d49208e7..ebaa329891c 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -817,3 +817,15 @@ drop table t1;
select 'c' like '\_' as want0;
want0
0
+create table t1 (id integer, a varchar(100) character set utf8 collate utf8_unicode_ci);
+insert into t1 values (1, 'Test');
+select * from t1 where soundex(a) = soundex('Test');
+id a
+1 Test
+select * from t1 where soundex(a) = soundex('TEST');
+id a
+1 Test
+select * from t1 where soundex(a) = soundex('test');
+id a
+1 Test
+drop table t1;
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index 42031be8f3c..214c2712665 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -666,3 +666,12 @@ drop table t1;
#
select 'c' like '\_' as want0;
+#
+# Bug #7730 Server crash using soundex on an utf8 table
+#
+create table t1 (id integer, a varchar(100) character set utf8 collate utf8_unicode_ci);
+insert into t1 values (1, 'Test');
+select * from t1 where soundex(a) = soundex('Test');
+select * from t1 where soundex(a) = soundex('TEST');
+select * from t1 where soundex(a) = soundex('test');
+drop table t1;
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 2a63c5355a4..d0190af042e 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1562,9 +1562,14 @@ void Item_func_soundex::fix_length_and_dec()
else return 0
*/
-static char get_scode(CHARSET_INFO *cs,char *ptr)
+static char soundex_toupper(char ch)
{
- uchar ch=my_toupper(cs,*ptr);
+ return (ch >= 'a' && ch <= 'z') ? ch - 'a' + 'A' : ch;
+}
+
+static char get_scode(char *ptr)
+{
+ uchar ch= soundex_toupper(*ptr);
if (ch < 'A' || ch > 'Z')
{
// Thread extended alfa (country spec)
@@ -1594,8 +1599,8 @@ String *Item_func_soundex::val_str(String *str)
from++; /* purecov: inspected */
if (from == end)
return &my_empty_string; // No alpha characters.
- *to++ = my_toupper(cs,*from); // Copy first letter
- last_ch = get_scode(cs,from); // code of the first letter
+ *to++ = soundex_toupper(*from); // Copy first letter
+ last_ch = get_scode(from); // code of the first letter
// for the first 'double-letter check.
// Loop on input letters until
// end of input (null) or output
@@ -1604,7 +1609,7 @@ String *Item_func_soundex::val_str(String *str)
{
if (!my_isalpha(cs,*from))
continue;
- ch=get_scode(cs,from);
+ ch=get_scode(from);
if ((ch != '0') && (ch != last_ch)) // if not skipped or double
{
*to++ = ch; // letter, copy to output