#At file:///home/kgeorge/mysql/work/B41437-5.0-bugteam/ based on revid:joro@stripped
2725 Georgi Kodinov 2009-01-08
Bug #41437: Value stored in 'case' lacks charset, causes segfault
Character set conversion functions were not expecting NULL
values returned when converting to string.
As a result they were dereferencing the NULL returned by ::val_str()
in such cases.
Fixed by checking and returning a constant Item_null instead of
Item_string.
modified:
mysql-test/r/mysql.result
mysql-test/t/mysql.test
sql/item.cc
sql/item.h
sql/item_strfunc.cc
per-file messages:
mysql-test/r/mysql.result
Bug #41437: test case
mysql-test/t/mysql.test
Bug #41437: test case
sql/item.cc
Bug #41437: check for NULL values and return Item_null
sql/item.h
Bug #41437: check for NULL values and return Item_null
sql/item_strfunc.cc
Bug #41437: check for NULL values and return Item_null
=== modified file 'mysql-test/r/mysql.result'
--- a/mysql-test/r/mysql.result 2008-12-11 17:26:03 +0000
+++ b/mysql-test/r/mysql.result 2009-01-08 13:04:39 +0000
@@ -186,4 +186,6 @@ delimiter
2
2
2
+@z:='1' @z=database()
+1 NULL
End of 5.0 tests
=== modified file 'mysql-test/t/mysql.test'
--- a/mysql-test/t/mysql.test 2008-12-11 17:26:03 +0000
+++ b/mysql-test/t/mysql.test 2009-01-08 13:04:39 +0000
@@ -309,4 +309,9 @@ EOF
--exec $MYSQL -c < $MYSQLTEST_VARDIR/tmp/bug38158.sql 2>&1
remove_file $MYSQLTEST_VARDIR/tmp/bug38158.sql;
+#
+# Bug #41437: Value stored in 'case' lacks charset, causees segfault
+#
+--exec $MYSQL -e "select @z:='1',@z=database()"
+
--echo End of 5.0 tests
=== modified file 'sql/item.cc'
--- a/sql/item.cc 2008-12-09 18:35:02 +0000
+++ b/sql/item.cc 2009-01-08 13:04:39 +0000
@@ -752,6 +752,14 @@ Item *Item::safe_charset_converter(CHARS
}
+Item *create_null_item (CHARSET_INFO *tocs, const char *name)
+{
+ Item *null_conv= new Item_null((char *)name);
+ null_conv->collation.set (tocs);
+ return null_conv;
+}
+
+
/*
Created mostly for mysql_prepare_table(). Important
when a string ENUM/SET column is described with a numeric default value:
@@ -768,6 +776,8 @@ Item *Item_num::safe_charset_converter(C
char buf[64];
String *s, tmp(buf, sizeof(buf), &my_charset_bin);
s= val_str(&tmp);
+ if (!s)
+ return create_null_item(tocs);
if ((conv= new Item_string(s->ptr(), s->length(), s->charset())))
{
conv->str_value.copy();
@@ -783,6 +793,8 @@ Item *Item_static_float_func::safe_chars
char buf[64];
String *s, tmp(buf, sizeof(buf), &my_charset_bin);
s= val_str(&tmp);
+ if (!s)
+ return create_null_item(tocs, func_name);
if ((conv= new Item_static_string_func(func_name, s->ptr(), s->length(),
s->charset())))
{
@@ -798,6 +810,8 @@ Item *Item_string::safe_charset_converte
Item_string *conv;
uint conv_errors;
String tmp, cstr, *ostr= val_str(&tmp);
+ if (!ostr)
+ return create_null_item(tocs);
cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
if (conv_errors || !(conv= new Item_string(cstr.ptr(), cstr.length(),
cstr.charset(),
@@ -824,6 +838,8 @@ Item *Item_param::safe_charset_converter
{
uint cnv_errors;
String *ostr= val_str(&cnvstr);
+ if (!ostr)
+ return create_null_item(tocs);
cnvitem->str_value.copy(ostr->ptr(), ostr->length(),
ostr->charset(), tocs, &cnv_errors);
if (cnv_errors)
@@ -841,6 +857,8 @@ Item *Item_static_string_func::safe_char
Item_string *conv;
uint conv_errors;
String tmp, cstr, *ostr= val_str(&tmp);
+ if (!ostr)
+ return create_null_item(tocs, func_name);
cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
if (conv_errors ||
!(conv= new Item_static_string_func(func_name,
@@ -5004,6 +5022,8 @@ Item *Item_hex_string::safe_charset_conv
Item_string *conv;
String tmp, *str= val_str(&tmp);
+ if (!str)
+ return create_null_item(tocs);
if (!(conv= new Item_string(str->ptr(), str->length(), tocs)))
return NULL;
conv->str_value.copy();
=== modified file 'sql/item.h'
--- a/sql/item.h 2008-08-15 20:13:27 +0000
+++ b/sql/item.h 2009-01-08 13:04:39 +0000
@@ -2709,3 +2709,4 @@ extern Cached_item *new_Cached_item(THD
extern Item_result item_cmp_type(Item_result a,Item_result b);
extern void resolve_const_item(THD *thd, Item **ref, Item *cmp_item);
extern bool field_is_equal_to_item(Field *field,Item *item);
+Item *create_null_item (CHARSET_INFO *tocs, const char *name = NULL);
=== modified file 'sql/item_strfunc.cc'
--- a/sql/item_strfunc.cc 2008-07-10 23:51:58 +0000
+++ b/sql/item_strfunc.cc 2009-01-08 13:04:39 +0000
@@ -1696,6 +1696,8 @@ Item *Item_func_sysconst::safe_charset_c
Item_string *conv;
uint conv_errors;
String tmp, cstr, *ostr= val_str(&tmp);
+ if (!ostr)
+ return create_null_item(tocs, fully_qualified_func_name());
cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs, &conv_errors);
if (conv_errors ||
!(conv= new Item_static_string_func(fully_qualified_func_name(),
| Thread |
|---|
| • bzr commit into mysql-5.0-bugteam branch (joro:2725) Bug#41437 | Georgi Kodinov | 8 Jan |