From 53eadeee6f581c0b526befa7b21c3e2d4ae470a6 Mon Sep 17 00:00:00 2001
From: unknown <gshchepa/uchum@gleb.loc>
Date: Fri, 25 May 2007 17:24:17 +0500
Subject: [PATCH] Fixed bug #28522: sometimes `mysqldump --hex-blob' overruned
 output buffer by '\0' byte.

The dump_table() function has been fixed to reserve 1 byte more for the
last '\0' byte of dumped string.


client/mysqldump.c:
  Fixed bug #28522.
  The dump_table() function has been fixed to reserve 1 byte more for the
  last '\0' byte of dumped string.
mysql-test/t/mysqldump.test:
  Updated test case for bug #28522.
mysql-test/r/mysqldump.result:
  Updated test case for bug #28522.
---
 client/mysqldump.c            |  7 +++++--
 mysql-test/r/mysqldump.result | 11 +++++++++++
 mysql-test/t/mysqldump.test   |  7 +++++++
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/client/mysqldump.c b/client/mysqldump.c
index 4f908b531b1..26235efafce 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -2529,15 +2529,18 @@ static void dump_table(char *table, char *db)
                   plus 2 bytes for '0x' prefix.
                   - In non-HEX mode we need up to 2 bytes per character,
                   plus 2 bytes for leading and trailing '\'' characters.
+                  Also we need to reserve 1 byte for terminating '\0'.
                 */
-                dynstr_realloc_checked(&extended_row,length * 2+2);
+                dynstr_realloc_checked(&extended_row,length * 2 + 2 + 1);
                 if (opt_hex_blob && is_blob)
                 {
                   dynstr_append_checked(&extended_row, "0x");
                   extended_row.length+= mysql_hex_string(extended_row.str +
                                                          extended_row.length,
                                                          row[i], length);
-                  extended_row.str[extended_row.length]= '\0';
+                  DBUG_ASSERT(extended_row.length+1 <= extended_row.max_length);
+                  /* mysql_hex_string() already terminated string by '\0' */
+                  DBUG_ASSERT(extended_row.str[extended_row.length] == '\0');
                 }
                 else
                 {
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index d9198ffeb48..25c4199e7a3 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -3310,5 +3310,16 @@ drop user user1;
 drop user user2;
 drop database mysqldump_test_db;
 #
+# Bug #28522: buffer overrun by '\0' byte using --hex-blob.
+#
+CREATE TABLE t1 (c1 INT, c2 LONGBLOB);
+INSERT INTO t1 SET c1=11, c2=REPEAT('q',509);
+CREATE TABLE `t1` (
+  `c1` int(11) default NULL,
+  `c2` longblob
+);
+INSERT INTO `t1` VALUES (11,0x7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171);
+DROP TABLE t1;
+#
 # End of 5.0 tests
 #
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 4c4690520c6..7df65f2b2e1 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -1528,7 +1528,14 @@ drop user user2;
 
 drop database mysqldump_test_db;
 
+--echo #
+--echo # Bug #28522: buffer overrun by '\0' byte using --hex-blob.
+--echo #
 
+CREATE TABLE t1 (c1 INT, c2 LONGBLOB);
+INSERT INTO t1 SET c1=11, c2=REPEAT('q',509);
+--exec $MYSQL_DUMP --skip-create --compact --hex-blob test t1
+DROP TABLE t1;
 
 --echo #
 --echo # End of 5.0 tests
-- 
2.30.9