Skip to content

Commit d4da131

Browse files
author
Alexey Botchkov
committed
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.
1 parent ffc5e00 commit d4da131

File tree

3 files changed

+38
-3
lines changed

3 files changed

+38
-3
lines changed

mysql-test/main/mysqltest_tracking_info.result

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,12 @@ SELECT @c:=10;
3939
@c:=10
4040
10
4141
SET @@session.session_track_user_variables=0;
42+
#
43+
# mdev-22337 Assertion `Alloced_length >= (str_length + length +
44+
net_length_size(length))' failed in Binary_string::q_net_store_data
45+
on long MULTIPOLYGON query with session_track_user_variables=1
46+
(optimized builds)
47+
#
48+
set @@session.session_track_user_variables=1;
49+
set @a=repeat('X', 1029);
50+
set @@session.session_track_user_variables=0;

mysql-test/main/mysqltest_tracking_info.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,15 @@ SET @b=NULL;
3434
SELECT @c:=10;
3535
--disable_session_track_info
3636
SET @@session.session_track_user_variables=0;
37+
38+
--echo #
39+
--echo # mdev-22337 Assertion `Alloced_length >= (str_length + length +
40+
--echo net_length_size(length))' failed in Binary_string::q_net_store_data
41+
--echo on long MULTIPOLYGON query with session_track_user_variables=1
42+
--echo (optimized builds)
43+
--echo #
44+
set @@session.session_track_user_variables=1;
45+
--enable_session_track_info
46+
set @a=repeat('X', 1029);
47+
--disable_session_track_info
48+
set @@session.session_track_user_variables=0;

sql/session_tracker.cc

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,12 +1198,18 @@ bool User_variables_tracker::store(THD *thd, String *buf)
11981198
auto var= m_changed_user_variables.at(i);
11991199
String value_str;
12001200
bool null_value;
1201+
uint length;
12011202

12021203
var->val_str(&null_value, &value_str, DECIMAL_MAX_SCALE);
1203-
buf->q_append(static_cast<char>(SESSION_TRACK_USER_VARIABLES));
1204-
ulonglong length= net_length_size(var->name.length) + var->name.length;
1204+
1205+
length= net_length_size(var->name.length) + var->name.length;
12051206
if (!null_value)
12061207
length+= net_length_size(value_str.length()) + value_str.length();
1208+
1209+
if (buf->reserve(sizeof(char) + length + net_length_size(length)))
1210+
return true;
1211+
1212+
buf->q_append(static_cast<char>(SESSION_TRACK_USER_VARIABLES));
12071213
buf->q_net_store_length(length);
12081214
buf->q_net_store_data(reinterpret_cast<const uchar*>(var->name.str),
12091215
var->name.length);
@@ -1259,7 +1265,7 @@ void Session_tracker::store(THD *thd, String *buf)
12591265
}
12601266

12611267
size_t length= buf->length() - start;
1262-
uchar *data= (uchar *)(buf->ptr() + start);
1268+
uchar *data;
12631269
uint size;
12641270

12651271
if ((size= net_length_size(length)) != 1)
@@ -1269,8 +1275,16 @@ void Session_tracker::store(THD *thd, String *buf)
12691275
buf->length(start); // it is safer to have 0-length block in case of error
12701276
return;
12711277
}
1278+
1279+
/*
1280+
The 'buf->reserve()' can change the buf->ptr() so we cannot
1281+
calculate the 'data' earlier.
1282+
*/
1283+
data= (uchar *)(buf->ptr() + start);
12721284
memmove(data + (size - 1), data, length);
12731285
}
1286+
else
1287+
data= (uchar *)(buf->ptr() + start);
12741288

12751289
net_store_length(data - 1, length);
12761290
}

0 commit comments

Comments
 (0)