Bug #14099846: EXPORT_SET CRASHES DUE TO OVERALLOCATION OF MEMORY
Backport the fix from 5.6 to 5.1 Base bug number : 11765562
This commit is contained in:
parent
e00f8f7f3b
commit
00fff1e12e
@ -3047,23 +3047,21 @@ err:
|
|||||||
String* Item_func_export_set::val_str(String* str)
|
String* Item_func_export_set::val_str(String* str)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
ulonglong the_set = (ulonglong) args[0]->val_int();
|
String yes_buf, no_buf, sep_buf;
|
||||||
String yes_buf, *yes;
|
const ulonglong the_set = (ulonglong) args[0]->val_int();
|
||||||
yes = args[1]->val_str(&yes_buf);
|
const String *yes= args[1]->val_str(&yes_buf);
|
||||||
String no_buf, *no;
|
const String *no= args[2]->val_str(&no_buf);
|
||||||
no = args[2]->val_str(&no_buf);
|
const String *sep= NULL;
|
||||||
String *sep = NULL, sep_buf ;
|
|
||||||
|
|
||||||
uint num_set_values = 64;
|
uint num_set_values = 64;
|
||||||
ulonglong mask = 0x1;
|
|
||||||
str->length(0);
|
str->length(0);
|
||||||
str->set_charset(collation.collation);
|
str->set_charset(collation.collation);
|
||||||
|
|
||||||
/* Check if some argument is a NULL value */
|
/* Check if some argument is a NULL value */
|
||||||
if (args[0]->null_value || args[1]->null_value || args[2]->null_value)
|
if (args[0]->null_value || args[1]->null_value || args[2]->null_value)
|
||||||
{
|
{
|
||||||
null_value=1;
|
null_value= true;
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Arg count can only be 3, 4 or 5 here. This is guaranteed from the
|
Arg count can only be 3, 4 or 5 here. This is guaranteed from the
|
||||||
@ -3076,37 +3074,56 @@ String* Item_func_export_set::val_str(String* str)
|
|||||||
num_set_values=64;
|
num_set_values=64;
|
||||||
if (args[4]->null_value)
|
if (args[4]->null_value)
|
||||||
{
|
{
|
||||||
null_value=1;
|
null_value= true;
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
/* Fall through */
|
/* Fall through */
|
||||||
case 4:
|
case 4:
|
||||||
if (!(sep = args[3]->val_str(&sep_buf))) // Only true if NULL
|
if (!(sep = args[3]->val_str(&sep_buf))) // Only true if NULL
|
||||||
{
|
{
|
||||||
null_value=1;
|
null_value= true;
|
||||||
return 0;
|
return NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
{
|
{
|
||||||
/* errors is not checked - assume "," can always be converted */
|
/* errors is not checked - assume "," can always be converted */
|
||||||
uint errors;
|
uint errors;
|
||||||
sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin, collation.collation, &errors);
|
sep_buf.copy(STRING_WITH_LEN(","), &my_charset_bin,
|
||||||
|
collation.collation, &errors);
|
||||||
sep = &sep_buf;
|
sep = &sep_buf;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
DBUG_ASSERT(0); // cannot happen
|
DBUG_ASSERT(0); // cannot happen
|
||||||
}
|
}
|
||||||
null_value=0;
|
null_value= false;
|
||||||
|
|
||||||
for (uint i = 0; i < num_set_values; i++, mask = (mask << 1))
|
const ulong max_allowed_packet= current_thd->variables.max_allowed_packet;
|
||||||
|
const uint num_separators= num_set_values > 0 ? num_set_values - 1 : 0;
|
||||||
|
const ulonglong max_total_length=
|
||||||
|
num_set_values * max(yes->length(), no->length()) +
|
||||||
|
num_separators * sep->length();
|
||||||
|
|
||||||
|
if (unlikely(max_total_length > max_allowed_packet))
|
||||||
|
{
|
||||||
|
push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||||
|
ER_WARN_ALLOWED_PACKET_OVERFLOWED,
|
||||||
|
ER(ER_WARN_ALLOWED_PACKET_OVERFLOWED),
|
||||||
|
func_name(), max_allowed_packet);
|
||||||
|
null_value= true;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint ix;
|
||||||
|
ulonglong mask;
|
||||||
|
for (ix= 0, mask=0x1; ix < num_set_values; ++ix, mask = (mask << 1))
|
||||||
{
|
{
|
||||||
if (the_set & mask)
|
if (the_set & mask)
|
||||||
str->append(*yes);
|
str->append(*yes);
|
||||||
else
|
else
|
||||||
str->append(*no);
|
str->append(*no);
|
||||||
if (i != num_set_values - 1)
|
if (ix != num_separators)
|
||||||
str->append(*sep);
|
str->append(*sep);
|
||||||
}
|
}
|
||||||
return str;
|
return str;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user