Commit 18e4f23a authored by Alexander Barkov's avatar Alexander Barkov

Bug#58371 Assertion failed: !s.uses_buffer_owned_by(this) with format string function

Introduced by the fix for bug#44766.

Problem: it's not correct to use args[0]->str_value as a buffer,
because args[0] may need this buffer for its own purposes.

Fix: adding a new class member tmp_value to use as return value.

  @ mysql-test/r/ctype_many.result
  @ mysql-test/t/ctype_many.test
  Adding tests

  @ sql/item_strfunc.cc
  Changing code into traditional style:
  use "str" as a buffer for the argument and tmp_value for the result value.

  @ sql/item_strfunc.h
  Adding tmp_value
parent 1c9515f6
...@@ -211,3 +211,19 @@ SELECT min(comment),count(*) FROM t1 GROUP BY ucs2_f; ...@@ -211,3 +211,19 @@ SELECT min(comment),count(*) FROM t1 GROUP BY ucs2_f;
DROP TABLE t1; DROP TABLE t1;
# End of 4.1 tests # End of 4.1 tests
--echo #
--echo # Start of 5.1 tests
--echo #
--echo #
--echo # Bug#58371 Assertion failed: !s.uses_buffer_owned_by(this) with format string function
--echo #
SET NAMES latin1;
DO CONVERT(CAST(SUBSTRING_INDEX(FORMAT(1,'1111'), FORMAT('','Zpq'),1)
AS BINARY(0)) USING utf8);
--echo #
--echo # End of 5.1 tests
--echo #
...@@ -2761,22 +2761,16 @@ String *Item_func_conv_charset::val_str(String *str) ...@@ -2761,22 +2761,16 @@ String *Item_func_conv_charset::val_str(String *str)
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
if (use_cached_value) if (use_cached_value)
return null_value ? 0 : &str_value; return null_value ? 0 : &str_value;
/* String *arg= args[0]->val_str(str);
Here we don't pass 'str' as a parameter to args[0]->val_str()
as 'str' may point to 'str_value' (e.g. see Item::save_in_field()),
which we use below to convert string.
Use argument's 'str_value' instead.
*/
String *arg= args[0]->val_str(&args[0]->str_value);
uint dummy_errors; uint dummy_errors;
if (!arg) if (!arg)
{ {
null_value=1; null_value=1;
return 0; return 0;
} }
null_value= str_value.copy(arg->ptr(),arg->length(),arg->charset(), null_value= tmp_value.copy(arg->ptr(), arg->length(), arg->charset(),
conv_charset, &dummy_errors); conv_charset, &dummy_errors);
return null_value ? 0 : check_well_formed_result(&str_value); return null_value ? 0 : check_well_formed_result(&tmp_value);
} }
void Item_func_conv_charset::fix_length_and_dec() void Item_func_conv_charset::fix_length_and_dec()
......
...@@ -713,6 +713,7 @@ class Item_func_quote :public Item_str_func ...@@ -713,6 +713,7 @@ class Item_func_quote :public Item_str_func
class Item_func_conv_charset :public Item_str_func class Item_func_conv_charset :public Item_str_func
{ {
bool use_cached_value; bool use_cached_value;
String tmp_value;
public: public:
bool safe; bool safe;
CHARSET_INFO *conv_charset; // keep it public CHARSET_INFO *conv_charset; // keep it public
......
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