Bug#58005 utf8 + get_format causes failed assertion: !str || str != Ptr'

Problem: When GET_FORMAT() is called two times from the upper
level function (e.g. LEAST in the bug report), on the second
call "res= args[0]->val_str(...)" and str point to the same
String object.

1. Fix: changing the order from
- get val_str into tmp_value then convert to str
to
- get val_str into str then convert to tmp_value

The new order is more correct: the purpose of "str" parameter
is exactly to call val_str() for arguments.
The purpose of String class members (like tmp_value) is to do further
actions on the result.
Doing it in the other way around give unexpected surprises.

2. Using str_value instead of str to do padding, for the same reason.
This commit is contained in:
Alexander Barkov 2010-11-12 13:12:15 +03:00
commit 1b583fa5da
3 changed files with 37 additions and 7 deletions

View file

@ -2456,14 +2456,14 @@ String *Item_char_typecast::val_str(String *str)
{
// Convert character set if differ
uint dummy_errors;
if (!(res= args[0]->val_str(&tmp_value)) ||
str->copy(res->ptr(), res->length(), from_cs,
cast_cs, &dummy_errors))
if (!(res= args[0]->val_str(str)) ||
tmp_value.copy(res->ptr(), res->length(), from_cs,
cast_cs, &dummy_errors))
{
null_value= 1;
return 0;
}
res= str;
res= &tmp_value;
}
res->set_charset(cast_cs);
@ -2497,9 +2497,9 @@ String *Item_char_typecast::val_str(String *str)
{
if (res->alloced_length() < (uint) cast_length)
{
str->alloc(cast_length);
str->copy(*res);
res= str;
str_value.alloc(cast_length);
str_value.copy(*res);
res= &str_value;
}
bzero((char*) res->ptr() + res->length(),
(uint) cast_length - res->length());