Commit d4da131c authored by Alexey Botchkov's avatar Alexey Botchkov

MDEV-22337 Assertion `Alloced_length >= (str_length + length + net_le…...

MDEV-22337 Assertion `Alloced_length >= (str_length + length + net_le… …ngth_size(length))' failed in Binary_string::q_net_store_data on long MULTIPOLYGON query with session_track_user_variables=1 (optimized builds).

We have to reserve enough space in String to use q_something().
Also pointer calculations fixed.
parent ffc5e00e
......@@ -39,3 +39,12 @@ SELECT @c:=10;
@c:=10
10
SET @@session.session_track_user_variables=0;
#
# mdev-22337 Assertion `Alloced_length >= (str_length + length +
net_length_size(length))' failed in Binary_string::q_net_store_data
on long MULTIPOLYGON query with session_track_user_variables=1
(optimized builds)
#
set @@session.session_track_user_variables=1;
set @a=repeat('X', 1029);
set @@session.session_track_user_variables=0;
......@@ -34,3 +34,15 @@ SET @b=NULL;
SELECT @c:=10;
--disable_session_track_info
SET @@session.session_track_user_variables=0;
--echo #
--echo # mdev-22337 Assertion `Alloced_length >= (str_length + length +
--echo net_length_size(length))' failed in Binary_string::q_net_store_data
--echo on long MULTIPOLYGON query with session_track_user_variables=1
--echo (optimized builds)
--echo #
set @@session.session_track_user_variables=1;
--enable_session_track_info
set @a=repeat('X', 1029);
--disable_session_track_info
set @@session.session_track_user_variables=0;
......@@ -1198,12 +1198,18 @@ bool User_variables_tracker::store(THD *thd, String *buf)
auto var= m_changed_user_variables.at(i);
String value_str;
bool null_value;
uint length;
var->val_str(&null_value, &value_str, DECIMAL_MAX_SCALE);
buf->q_append(static_cast<char>(SESSION_TRACK_USER_VARIABLES));
ulonglong length= net_length_size(var->name.length) + var->name.length;
length= net_length_size(var->name.length) + var->name.length;
if (!null_value)
length+= net_length_size(value_str.length()) + value_str.length();
if (buf->reserve(sizeof(char) + length + net_length_size(length)))
return true;
buf->q_append(static_cast<char>(SESSION_TRACK_USER_VARIABLES));
buf->q_net_store_length(length);
buf->q_net_store_data(reinterpret_cast<const uchar*>(var->name.str),
var->name.length);
......@@ -1259,7 +1265,7 @@ void Session_tracker::store(THD *thd, String *buf)
}
size_t length= buf->length() - start;
uchar *data= (uchar *)(buf->ptr() + start);
uchar *data;
uint size;
if ((size= net_length_size(length)) != 1)
......@@ -1269,8 +1275,16 @@ void Session_tracker::store(THD *thd, String *buf)
buf->length(start); // it is safer to have 0-length block in case of error
return;
}
/*
The 'buf->reserve()' can change the buf->ptr() so we cannot
calculate the 'data' earlier.
*/
data= (uchar *)(buf->ptr() + start);
memmove(data + (size - 1), data, length);
}
else
data= (uchar *)(buf->ptr() + start);
net_store_length(data - 1, length);
}
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