Skip to content

Commit

Permalink
Fix mysqldump handling of varbinary columns
Browse files Browse the repository at this point in the history
Summary:
https://bugs.mysql.com/bug.php?id=96053

8.0.13 added _binary tags to blobs in the mysqldump output. However,
memory allocated for the insert statement did not account of the 8 bytes
of the "_binary " string properly. This resulted in mysqldump writing
to memory beyond the buffer allocated for the string buffer before it
is reallocated with a new larger size.

The fix is to account for the 8 bytes of the "_binary " string during
the realloc calculation.

Reviewed By: lloyd

Differential Revision: D16088056 (facebook@5e15108)

fbshipit-source-id: 7d8cd4398f1
  • Loading branch information
Herman Lee authored and inikep committed Jul 16, 2021
1 parent c6ab001 commit 5a7bdea
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 3 deletions.
7 changes: 4 additions & 3 deletions client/mysqldump.cc
Expand Up @@ -4178,12 +4178,13 @@ static void dump_table(char *table, char *db) {
- In non-HEX mode we need up to 2 bytes per character,
plus 2 bytes for leading and trailing '\'' characters
and reserve 1 byte for terminating '\0'.
Also we need to reserve 8 bytes for "_binary ".
In addition to this, for the blob type, we need to
reserve for the "_binary " string that gets added in
front of the string in the dump.
*/
if (opt_hex_blob && is_blob) {
dynstr_realloc_checked(&extended_row, length * 2 + 2 + 1);
dynstr_realloc_checked(&extended_row, length * 2 + 8 + 2 + 1);
dynstr_append_checked(&extended_row, "0x");
extended_row.length += mysql_hex_string(
extended_row.str + extended_row.length, row[i], length);
Expand All @@ -4193,8 +4194,8 @@ static void dump_table(char *table, char *db) {
DBUG_ASSERT(extended_row.str[extended_row.length] == '\0');
} else {
dynstr_realloc_checked(
&extended_row,
length * 2 + 2 + 1 + (is_blob ? strlen("_binary ") : 0));
&extended_row, length * 2 + 8 + 2 + 1 +
(is_blob ? strlen("_binary ") : 0));
if (is_blob) {
/*
inform SQL parser that this string isn't in
Expand Down
12 changes: 12 additions & 0 deletions mysql-test/r/mysqldump-binary.result
Expand Up @@ -79,3 +79,15 @@ ST_AsText(g) FROM t1;
u='basic' HEX(b)='EE0C6D03C34C11E5B1640026B977EB17' HEX(blo)='EE0C6D03C34C11E5B1640026B977EB17' HEX(g)='000000000101000000000000000000F03F000000000000F03F' HEX(bi)='EE0C6D03C34C11E5' ST_AsText(g)
1 1 1 1 1 POINT(1 1)
DROP TABLE t1;
CREATE TABLE t1 (pk INT, v1 VARCHAR(255), v2 VARCHAR(255), v3 VARCHAR(255), v4 VARCHAR(128), v5 VARCHAR(64), v6 VARCHAR(16), v7 VARCHAR(16), v8 VARCHAR (8), v9 VARBINARY(32), v10 VARBINARY(32));
SELECT '12345678901234567890123456789012345678901234567890' INTO @s;
SELECT CONCAT(@s, @s, @s, @s, @s) INTO @s1;
INSERT INTO t1 VALUES (1, @s1, @s1, @s1, SUBSTRING(@s1, 1, 128), SUBSTRING(@s1, 1, 64), SUBSTRING(@s1, 1, 16), SUBSTRING(@s1, 1, 16), SUBSTRING(@s1, 1, 8), '', 'NULL');
CHECKSUM TABLE t1;
Table Checksum
test.t1 869635727
DROP TABLE t1;
CHECKSUM TABLE t1;
Table Checksum
test.t1 869635727
DROP TABLE t1;
13 changes: 13 additions & 0 deletions mysql-test/t/mysqldump-binary.test
Expand Up @@ -72,3 +72,16 @@ ST_AsText(g) FROM t1;

DROP TABLE t1;
--remove_file $MYSQLTEST_VARDIR/tmp/bug22601255.sql

# Verify mysqldump's memory buffer accounts for "_binary " properly
CREATE TABLE t1 (pk INT, v1 VARCHAR(255), v2 VARCHAR(255), v3 VARCHAR(255), v4 VARCHAR(128), v5 VARCHAR(64), v6 VARCHAR(16), v7 VARCHAR(16), v8 VARCHAR (8), v9 VARBINARY(32), v10 VARBINARY(32));
SELECT '12345678901234567890123456789012345678901234567890' INTO @s;
SELECT CONCAT(@s, @s, @s, @s, @s) INTO @s1;
INSERT INTO t1 VALUES (1, @s1, @s1, @s1, SUBSTRING(@s1, 1, 128), SUBSTRING(@s1, 1, 64), SUBSTRING(@s1, 1, 16), SUBSTRING(@s1, 1, 16), SUBSTRING(@s1, 1, 8), '', 'NULL');
CHECKSUM TABLE t1;
--exec $MYSQL_DUMP test t1 > $MYSQLTEST_VARDIR/tmp/bug96053.sql
DROP TABLE t1;
--exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/bug96053.sql
CHECKSUM TABLE t1;
DROP TABLE t1;
--remove_file $MYSQLTEST_VARDIR/tmp/bug96053.sql

0 comments on commit 5a7bdea

Please sign in to comment.