diff --git a/mysql-test/main/column_compression.result b/mysql-test/main/column_compression.result index 243a118a706..b3d4caad555 100644 --- a/mysql-test/main/column_compression.result +++ b/mysql-test/main/column_compression.result @@ -1360,3 +1360,16 @@ SELECT a, LENGTH(a) FROM t1; a LENGTH(a) aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 255 DROP TABLE t1; +# +# MDEV-14929 - AddressSanitizer: memcpy-param-overlap in +# Field_longstr::compress +# +CREATE TABLE t1(b BLOB COMPRESSED); +INSERT INTO t1 VALUES('foo'),('bar'); +SET SESSION optimizer_switch = 'derived_merge=off'; +SELECT * FROM ( SELECT * FROM t1 ) AS sq ORDER BY b; +b +bar +foo +SET SESSION optimizer_switch=DEFAULT; +DROP TABLE t1; diff --git a/mysql-test/main/column_compression.test b/mysql-test/main/column_compression.test index d3f848144b6..6d6ed3d3993 100644 --- a/mysql-test/main/column_compression.test +++ b/mysql-test/main/column_compression.test @@ -79,3 +79,15 @@ INSERT INTO t1 VALUES(REPEAT('a', 255)); SET column_compression_threshold=DEFAULT; SELECT a, LENGTH(a) FROM t1; DROP TABLE t1; + + +--echo # +--echo # MDEV-14929 - AddressSanitizer: memcpy-param-overlap in +--echo # Field_longstr::compress +--echo # +CREATE TABLE t1(b BLOB COMPRESSED); +INSERT INTO t1 VALUES('foo'),('bar'); +SET SESSION optimizer_switch = 'derived_merge=off'; +SELECT * FROM ( SELECT * FROM t1 ) AS sq ORDER BY b; +SET SESSION optimizer_switch=DEFAULT; +DROP TABLE t1; diff --git a/sql/field.cc b/sql/field.cc index 47af9a8b1f7..a7214bee6d6 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8699,17 +8699,22 @@ int Field_blob_compressed::store(const char *from, size_t length, { ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; uint to_length= (uint)MY_MIN(max_data_length(), field_charset->mbmaxlen * length + 1); + String tmp(from, length, cs); int rc; - if (value.alloc(to_length)) - { - set_ptr((uint32) 0, NULL); - return -1; - } + if (from >= value.ptr() && from <= value.end() && tmp.copy(from, length, cs)) + goto oom; - rc= compress((char*) value.ptr(), &to_length, from, (uint)length, cs); + if (value.alloc(to_length)) + goto oom; + + rc= compress((char*) value.ptr(), &to_length, tmp.ptr(), (uint) length, cs); set_ptr(to_length, (uchar*) value.ptr()); return rc; + +oom: + set_ptr((uint32) 0, NULL); + return -1; }