← Back to team overview

maria-developers team mailing list archive

Correct parsing of BINLOG 'XXX' with comment inside

 

Hi Bar,

Currently if we have generated the sql file using mysqlbinlog -v and
if we have big statement binlog
, then mysqlbinlog add comment in between of Binlog 'XXX' statement ,
but unfortunately base64_decode
does not understands it, and it through error since # is not a base64 char

This patches solves this. There are 2 patches one for 5.5 and 2nd for
10.0 and above
Please review it.
commit 18e21756685b75cfc89adef0b24e183196aedc02
Author: Sachin <sachin.setiya@xxxxxxxxxxx>
Date:   Mon Sep 10 13:58:57 2018 +0530

    MDEV-10362 mysqlbinlog verbose output cannot be decoded
    
    base64_encode does not correctly parse comments inside of base64 string.
    
    This patch fixes that.

diff --git a/mysql-test/suite/rpl/r/rpl_mysqlbinlog.result b/mysql-test/suite/rpl/r/rpl_mysqlbinlog.result
new file mode 100644
index 00000000000..f0f609220d9
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_mysqlbinlog.result
@@ -0,0 +1,13 @@
+include/master-slave.inc
+[connection master]
+create table t1(a int , b int);
+#202 entry so that binlog query is split
+select count(*) from t1;
+count(*)
+202
+DROP TABLE t1;
+select count(*) from t1;
+count(*)
+202
+DROP TABLE t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_mysqlbinlog.test b/mysql-test/suite/rpl/t/rpl_mysqlbinlog.test
new file mode 100644
index 00000000000..2d458a51ab6
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_mysqlbinlog.test
@@ -0,0 +1,30 @@
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+
+connection master;
+create table t1(a int , b int);
+
+--echo #202 entry so that binlog query is split
+--let str=insert into t1 values(1,1),
+--let counter=200
+while ($counter)
+{
+  --let str=$str(1,1),
+  --dec $counter
+}
+--let str=$str(1,1)
+--disable_query_log
+--eval $str
+--enable_query_log
+select count(*) from t1;
+--let $MYSQLD_DATADIR= `SELECT @@datadir`
+--exec $MYSQL_BINLOG -vvv $MYSQLD_DATADIR/master-bin.000001 > $MYSQTEST_VARDIR/tmp/a.binlog
+
+connection master;
+DROP TABLE t1;
+
+--exec $MYSQL < $MYSQTEST_VARDIR/tmp/a.binlog
+select count(*) from t1;
+DROP TABLE t1;
+
+--source include/rpl_end.inc
diff --git a/mysys/base64.c b/mysys/base64.c
index b48bcb85e03..3942b26b0b2 100644
--- a/mysys/base64.c
+++ b/mysys/base64.c
@@ -170,6 +170,8 @@ base64_decode(const char *src_base, size_t len,
 
     SKIP_SPACE(src, i, len);
 
+    while(*src == '#')
+      while(*src++ != '\n'){}
     c += pos(*src++);
     c <<= 6;
     i++;
commit 15a8e5da3b155a7cc6063802a3cf2a9987444097
Author: Sachin <sachin.setiya@xxxxxxxxxxx>
Date:   Mon Sep 10 13:59:27 2018 +0530

    MDEV-10362 mysqlbinlog verbose output cannot be decoded
    
    base64_encode does not correctly parse comments inside of base64 string.
    
    This patch fixes that.

diff --git a/mysql-test/suite/rpl/r/rpl_mysqlbinlog.result b/mysql-test/suite/rpl/r/rpl_mysqlbinlog.result
new file mode 100644
index 00000000000..f0f609220d9
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_mysqlbinlog.result
@@ -0,0 +1,13 @@
+include/master-slave.inc
+[connection master]
+create table t1(a int , b int);
+#202 entry so that binlog query is split
+select count(*) from t1;
+count(*)
+202
+DROP TABLE t1;
+select count(*) from t1;
+count(*)
+202
+DROP TABLE t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_mysqlbinlog.test b/mysql-test/suite/rpl/t/rpl_mysqlbinlog.test
new file mode 100644
index 00000000000..2d458a51ab6
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_mysqlbinlog.test
@@ -0,0 +1,30 @@
+--source include/have_binlog_format_row.inc
+--source include/master-slave.inc
+
+connection master;
+create table t1(a int , b int);
+
+--echo #202 entry so that binlog query is split
+--let str=insert into t1 values(1,1),
+--let counter=200
+while ($counter)
+{
+  --let str=$str(1,1),
+  --dec $counter
+}
+--let str=$str(1,1)
+--disable_query_log
+--eval $str
+--enable_query_log
+select count(*) from t1;
+--let $MYSQLD_DATADIR= `SELECT @@datadir`
+--exec $MYSQL_BINLOG -vvv $MYSQLD_DATADIR/master-bin.000001 > $MYSQTEST_VARDIR/tmp/a.binlog
+
+connection master;
+DROP TABLE t1;
+
+--exec $MYSQL < $MYSQTEST_VARDIR/tmp/a.binlog
+select count(*) from t1;
+DROP TABLE t1;
+
+--source include/rpl_end.inc
diff --git a/mysys/base64.c b/mysys/base64.c
index 265b2f22aad..c99728962ef 100644
--- a/mysys/base64.c
+++ b/mysys/base64.c
@@ -201,7 +201,22 @@ my_base64_decoder_skip_spaces(MY_BASE64_DECODER *decoder)
     decoder->error= 1; /* Unexpected end-of-input found */
   return TRUE;
 }
-
+/**
+ * Skip all the comments inside of base64 encoding
+ *
+ * @param decode base64 decoding stream
+ *
+ * @return void
+ * */
+static inline void
+my_base64_skip_comments(MY_BASE64_DECODER *decoder)
+{
+  my_base64_decoder_skip_spaces(decoder);
+  const char* src= decoder->src;
+  while(*src == '#')
+    while (*src++ != '\n'){}
+  decoder->src= src;
+}
 
 /**
  * Convert the next character in a base64 encoded stream
@@ -323,11 +338,12 @@ base64_decode(const char *src_base, size_t len,
   decoder.end= src_base + len;
   decoder.error= 0;
   decoder.mark= 0;
-
+  uint i=1;
   for ( ; ; )
   {
     decoder.c= 0;
     decoder.state= 0;
+    my_base64_skip_comments(&decoder);
 
     if (my_base64_decoder_getch(&decoder) ||
         my_base64_decoder_getch(&decoder) ||
@@ -346,6 +362,7 @@ base64_decode(const char *src_base, size_t len,
         break;
       decoder.mark= 0;
     }
+    i++;
   }
 
   /* Return error if there are more non-space characters */

Follow ups