diff options
-rw-r--r-- | mysql-test/r/ctype_utf8.result | 31 | ||||
-rw-r--r-- | mysql-test/r/func_misc.result | 7 | ||||
-rw-r--r-- | mysql-test/t/ctype_utf8.test | 20 | ||||
-rw-r--r-- | mysql-test/t/func_misc.test | 11 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 42 |
5 files changed, 111 insertions, 0 deletions
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index e14b54b59a3..13e1092cb98 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1898,6 +1898,37 @@ CONVERT(a, CHAR) CONVERT(b, CHAR) 70000 1092 DROP TABLE t1; End of 5.0 tests +SELECT LENGTH(RPAD(0.0115E88, 61297, _utf8'яэюя')); +LENGTH(RPAD(0.0115E88, 61297, _utf8'яэюя')) +122587 +SELECT LENGTH(RPAD(0.0115E88, 61297, _utf8'йцуя')); +LENGTH(RPAD(0.0115E88, 61297, _utf8'йцуя')) +122587 +SELECT HEX(RPAD(0x20, 2, _utf8 0xD18F)); +HEX(RPAD(0x20, 2, _utf8 0xD18F)) +20D1 +SELECT HEX(RPAD(0x20, 4, _utf8 0xD18F)); +HEX(RPAD(0x20, 4, _utf8 0xD18F)) +20D18FD1 +SELECT HEX(LPAD(0x20, 2, _utf8 0xD18F)); +HEX(LPAD(0x20, 2, _utf8 0xD18F)) +D120 +SELECT HEX(LPAD(0x20, 4, _utf8 0xD18F)); +HEX(LPAD(0x20, 4, _utf8 0xD18F)) +D18FD120 +SELECT HEX(RPAD(_utf8 0xD18F, 3, 0x20)); +HEX(RPAD(_utf8 0xD18F, 3, 0x20)) +D18F20 +SELECT HEX(LPAD(_utf8 0xD18F, 3, 0x20)); +HEX(LPAD(_utf8 0xD18F, 3, 0x20)) +20D18F +SELECT HEX(INSERT(_utf8 0xD18F, 2, 1, 0x20)); +HEX(INSERT(_utf8 0xD18F, 2, 1, 0x20)) +D120 +SELECT HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)); +HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)) +D120D18E +End of 5.1 tests Start of 5.4 tests SET NAMES utf8mb3; SHOW VARIABLES LIKE 'character_set_results%'; diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index 85448a258e4..9ea02d5a9e3 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -375,4 +375,11 @@ GREATEST(a, (SELECT b FROM t1 LIMIT 1)) 3 1 DROP TABLE t1; +SELECT INET_NTOA(0); +INET_NTOA(0) +0.0.0.0 +SELECT '1' IN ('1', INET_NTOA(0)); +'1' IN ('1', INET_NTOA(0)) +1 End of 5.1 tests +End of tests diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 5b665e24958..318bbdca0c7 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -1439,6 +1439,26 @@ DROP TABLE t1; --echo End of 5.0 tests +# +# Bug #57272: crash in rpad() when using utf8 +# +SELECT LENGTH(RPAD(0.0115E88, 61297, _utf8'яэюя')); +SELECT LENGTH(RPAD(0.0115E88, 61297, _utf8'йцуя')); +SELECT HEX(RPAD(0x20, 2, _utf8 0xD18F)); +SELECT HEX(RPAD(0x20, 4, _utf8 0xD18F)); +SELECT HEX(LPAD(0x20, 2, _utf8 0xD18F)); +SELECT HEX(LPAD(0x20, 4, _utf8 0xD18F)); + +SELECT HEX(RPAD(_utf8 0xD18F, 3, 0x20)); +SELECT HEX(LPAD(_utf8 0xD18F, 3, 0x20)); + +SELECT HEX(INSERT(_utf8 0xD18F, 2, 1, 0x20)); +SELECT HEX(INSERT(_utf8 0xD18FD18E, 2, 1, 0x20)); + + +--echo End of 5.1 tests + + --echo Start of 5.4 tests # diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index ec71e950ca7..2251ae45b3f 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -504,4 +504,15 @@ SELECT DISTINCT GREATEST(a, (SELECT b FROM t1 LIMIT 1)) FROM t1 UNION SELECT 1; DROP TABLE t1; + +# +# Bug #57283: inet_ntoa() crashes +# +SELECT INET_NTOA(0); +SELECT '1' IN ('1', INET_NTOA(0)); + + --echo End of 5.1 tests + + +--echo End of tests diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 6d3514bf356..d8a21b5a4a2 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1184,6 +1184,20 @@ String *Item_func_insert::val_str(String *str) if ((length < 0) || (length > res->length())) length= res->length(); + /* + There is one exception not handled (intentionaly) by the character set + aggregation code. If one string is strong side and is binary, and + another one is weak side and is a multi-byte character string, + then we need to operate on the second string in terms on bytes when + calling ::numchars() and ::charpos(), rather than in terms of characters. + Lets substitute its character set to binary. + */ + if (collation.collation == &my_charset_bin) + { + res->set_charset(&my_charset_bin); + res2->set_charset(&my_charset_bin); + } + /* start and length are now sufficiently valid to pass to charpos function */ start= res->charpos((int) start); length= res->charpos((int) length, (uint32) start); @@ -2724,6 +2738,20 @@ String *Item_func_rpad::val_str(String *str) /* Set here so that rest of code sees out-of-bound value as such. */ if ((ulonglong) count > INT_MAX32) count= INT_MAX32; + /* + There is one exception not handled (intentionaly) by the character set + aggregation code. If one string is strong side and is binary, and + another one is weak side and is a multi-byte character string, + then we need to operate on the second string in terms on bytes when + calling ::numchars() and ::charpos(), rather than in terms of characters. + Lets substitute its character set to binary. + */ + if (collation.collation == &my_charset_bin) + { + res->set_charset(&my_charset_bin); + rpad->set_charset(&my_charset_bin); + } + if (count <= (res_char_length= res->numchars())) { // String to pad is big enough res->length(res->charpos((int) count)); // Shorten result if longer @@ -2813,6 +2841,20 @@ String *Item_func_lpad::val_str(String *str) if ((ulonglong) count > INT_MAX32) count= INT_MAX32; + /* + There is one exception not handled (intentionaly) by the character set + aggregation code. If one string is strong side and is binary, and + another one is weak side and is a multi-byte character string, + then we need to operate on the second string in terms on bytes when + calling ::numchars() and ::charpos(), rather than in terms of characters. + Lets substitute its character set to binary. + */ + if (collation.collation == &my_charset_bin) + { + res->set_charset(&my_charset_bin); + pad->set_charset(&my_charset_bin); + } + res_char_length= res->numchars(); if (count <= res_char_length) |