From d4da131cff004e4157b755e417c49daef45ca80e Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Wed, 29 Apr 2020 11:40:14 +0400 Subject: =?UTF-8?q?MDEV-22337=20Assertion=20`Alloced=5Flength=20>=3D=20(st?= =?UTF-8?q?r=5Flength=20+=20length=20+=20net=5Fle=E2=80=A6=20=E2=80=A6ngth?= =?UTF-8?q?=5Fsize(length))'=20failed=20in=20Binary=5Fstring::q=5Fnet=5Fst?= =?UTF-8?q?ore=5Fdata=20on=20long=20MULTIPOLYGON=20query=20with=20session?= =?UTF-8?q?=5Ftrack=5Fuser=5Fvariables=3D1=20(optimized=20builds).?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We have to reserve enough space in String to use q_something(). Also pointer calculations fixed. --- sql/session_tracker.cc | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) (limited to 'sql') diff --git a/sql/session_tracker.cc b/sql/session_tracker.cc index e1c2ec37644..ed422fa025d 100644 --- a/sql/session_tracker.cc +++ b/sql/session_tracker.cc @@ -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(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(SESSION_TRACK_USER_VARIABLES)); buf->q_net_store_length(length); buf->q_net_store_data(reinterpret_cast(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); } -- cgit v1.2.1