From d4da131cff004e4157b755e417c49daef45ca80e Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Wed, 29 Apr 2020 11:40:14 +0400 Subject: [PATCH] =?UTF-8?q?MDEV-22337=20Assertion=20`Alloced=5Flength=20>?= =?UTF-8?q?=3D=20(str=5Flength=20+=20length=20+=20net=5Fle=E2=80=A6=20?= =?UTF-8?q?=E2=80=A6ngth=5Fsize(length))'=20failed=20in=20Binary=5Fstring:?= =?UTF-8?q?:q=5Fnet=5Fstore=5Fdata=20on=20long=20MULTIPOLYGON=20query=20wi?= =?UTF-8?q?th=20session=5Ftrack=5Fuser=5Fvariables=3D1=20(optimized=20buil?= =?UTF-8?q?ds).?= 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. --- .../main/mysqltest_tracking_info.result | 9 +++++++++ mysql-test/main/mysqltest_tracking_info.test | 12 +++++++++++ sql/session_tracker.cc | 20 ++++++++++++++++--- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/mysql-test/main/mysqltest_tracking_info.result b/mysql-test/main/mysqltest_tracking_info.result index d2eaa5afea8..0fb16b67d4b 100644 --- a/mysql-test/main/mysqltest_tracking_info.result +++ b/mysql-test/main/mysqltest_tracking_info.result @@ -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; diff --git a/mysql-test/main/mysqltest_tracking_info.test b/mysql-test/main/mysqltest_tracking_info.test index 405b920051a..b3f05781d89 100644 --- a/mysql-test/main/mysqltest_tracking_info.test +++ b/mysql-test/main/mysqltest_tracking_info.test @@ -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; 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); }