Commit 7ad0e1c5 authored by Tor Didriksen's avatar Tor Didriksen

Bug#12368495 CRASH AND/OR VALGRIND ERRORS WITH REVERSE FUNCTION AND CHARSET CONVERTS

Item_func_trim::val_str: we were using the non-mb algorithm for skipping leading spaces
in a multibyte-charset string.
parent d7ab3bf5
...@@ -1005,6 +1005,7 @@ String *Item_func_reverse::val_str(String *str) ...@@ -1005,6 +1005,7 @@ String *Item_func_reverse::val_str(String *str)
if ((l= my_ismbchar(res->charset(),ptr,end))) if ((l= my_ismbchar(res->charset(),ptr,end)))
{ {
tmp-= l; tmp-= l;
DBUG_ASSERT(tmp >= tmp_value.ptr());
memcpy(tmp,ptr,l); memcpy(tmp,ptr,l);
ptr+= l; ptr+= l;
} }
...@@ -1751,18 +1752,35 @@ String *Item_func_trim::val_str(String *str) ...@@ -1751,18 +1752,35 @@ String *Item_func_trim::val_str(String *str)
ptr= (char*) res->ptr(); ptr= (char*) res->ptr();
end= ptr+res->length(); end= ptr+res->length();
r_ptr= remove_str->ptr(); r_ptr= remove_str->ptr();
while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length))
ptr+=remove_length;
#ifdef USE_MB #ifdef USE_MB
if (use_mb(res->charset())) if (use_mb(res->charset()))
{ {
while (ptr + remove_length <= end)
{
uint num_bytes= 0;
while (num_bytes < remove_length)
{
uint len;
if ((len= my_ismbchar(res->charset(), ptr + num_bytes, end)))
num_bytes+= len;
else
++num_bytes;
}
if (num_bytes != remove_length)
break;
if (memcmp(ptr, r_ptr, remove_length))
break;
ptr+= remove_length;
}
char *p=ptr; char *p=ptr;
register uint32 l; register uint32 l;
loop: loop:
while (ptr + remove_length < end) while (ptr + remove_length < end)
{ {
if ((l=my_ismbchar(res->charset(), ptr,end))) ptr+=l; if ((l= my_ismbchar(res->charset(), ptr,end)))
else ++ptr; ptr+= l;
else
++ptr;
} }
if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length)) if (ptr + remove_length == end && !memcmp(ptr,r_ptr,remove_length))
{ {
...@@ -1775,6 +1793,8 @@ String *Item_func_trim::val_str(String *str) ...@@ -1775,6 +1793,8 @@ String *Item_func_trim::val_str(String *str)
else else
#endif /* USE_MB */ #endif /* USE_MB */
{ {
while (ptr+remove_length <= end && !memcmp(ptr,r_ptr,remove_length))
ptr+=remove_length;
while (ptr + remove_length <= end && while (ptr + remove_length <= end &&
!memcmp(end-remove_length,r_ptr,remove_length)) !memcmp(end-remove_length,r_ptr,remove_length))
end-=remove_length; end-=remove_length;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment