diff options
author | Jonathan Perkin <jonathan.perkin@oracle.com> | 2010-12-16 11:13:58 +0100 |
---|---|---|
committer | Jonathan Perkin <jonathan.perkin@oracle.com> | 2010-12-16 11:13:58 +0100 |
commit | 3d799bdffd04beba3dad4f1ece915104b0284157 (patch) | |
tree | 83c2beab0fb52424ab77dcb1449a3f394f0d0fe1 /sql/item_strfunc.cc | |
parent | c7e273b5313fb71c20444e8ee70423b44fbd02c3 (diff) | |
parent | 93efc7e2c4bc8cffa235f2406db3bdaf4180189d (diff) | |
download | mariadb-git-3d799bdffd04beba3dad4f1ece915104b0284157.tar.gz |
Merge from mysql-5.5.8-release
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r-- | sql/item_strfunc.cc | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 89c1e785c71..c71d8226f77 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -1080,9 +1080,15 @@ String *Item_func_replace::val_str(String *str) search=res2->ptr(); search_end=search+from_length; redo: + DBUG_ASSERT(res->ptr() || !offset); ptr=res->ptr()+offset; strend=res->ptr()+res->length(); - end=strend-from_length+1; + /* + In some cases val_str() can return empty string + with ptr() == NULL and length() == 0. + Let's check strend to avoid overflow. + */ + end= strend ? strend - from_length + 1 : NULL; while (ptr < end) { if (*ptr == *search) @@ -1184,6 +1190,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); @@ -2725,6 +2745,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 @@ -2814,6 +2848,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) |