From 6665ca25afdeea7a3fd2db0094d3f67af37e14ba Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Mon, 17 Jan 2011 15:11:33 +0300 Subject: [PATCH] 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 --- mysql-test/r/ctype_many.result | 15 +++++++++++++++ mysql-test/t/ctype_many.test | 16 ++++++++++++++++ sql/item_strfunc.cc | 12 +++--------- sql/item_strfunc.h | 1 + 4 files changed, 35 insertions(+), 9 deletions(-) diff --git a/mysql-test/r/ctype_many.result b/mysql-test/r/ctype_many.result index 89e05bf4484..dbec746cdae 100644 --- a/mysql-test/r/ctype_many.result +++ b/mysql-test/r/ctype_many.result @@ -1683,3 +1683,18 @@ ARMENIAN CAPIT DA 2 ARMENIAN CAPIT ECH 2 ARMENIAN CAPIT ZA 2 DROP TABLE t1; +# +# Start of 5.1 tests +# +# +# Bug#58371 Assertion failed: !s.uses_buffer_owned_by(this) with format string function +# +SET NAMES latin1; +DO CONVERT(CAST(SUBSTRING_INDEX(FORMAT(1,'1111'), FORMAT('','Zpq'),1) +AS BINARY(0)) USING utf8); +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'Zpq' +Warning 1292 Truncated incorrect BINARY(0) value: '1.' +# +# End of 5.1 tests +# diff --git a/mysql-test/t/ctype_many.test b/mysql-test/t/ctype_many.test index 0903c3dd7fa..84048761228 100644 --- a/mysql-test/t/ctype_many.test +++ b/mysql-test/t/ctype_many.test @@ -211,3 +211,19 @@ SELECT min(comment),count(*) FROM t1 GROUP BY ucs2_f; DROP TABLE t1; # 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 # diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 204a2dfc663..c637c9c29b8 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2761,22 +2761,16 @@ String *Item_func_conv_charset::val_str(String *str) DBUG_ASSERT(fixed == 1); if (use_cached_value) return null_value ? 0 : &str_value; - /* - 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); + String *arg= args[0]->val_str(str); uint dummy_errors; if (!arg) { null_value=1; 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); - 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() diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 6645a4c637a..408062ddc08 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -713,6 +713,7 @@ public: class Item_func_conv_charset :public Item_str_func { bool use_cached_value; + String tmp_value; public: bool safe; CHARSET_INFO *conv_charset; // keep it public