|
| 1 | +# |
| 2 | +# Purpose: |
| 3 | +# This test ensures that the mysql client is able to properly handle the |
| 4 | +# binary data sequence 0x5c00, i.e. the null-terminating character \0, in a |
| 5 | +# string when --binary-mode is enabled. Specifically, this sequence is valid to |
| 6 | +# appear anywhere within a binary data string, and it should not end the string |
| 7 | +# or SQL command. Additionally, \0 outside of a string should still end the |
| 8 | +# query. |
| 9 | +# |
| 10 | +# Methodology: |
| 11 | +# This test initially inserts data with binary strings containing \0. To |
| 12 | +# ensure the mysql client is able to process this data correctly, perl is used |
| 13 | +# to create a SQL file that contains \0 in strings, and this file is used as |
| 14 | +# input into the client. The row data is then validated by searching for binary |
| 15 | +# zeros in mysqldump output. |
| 16 | +# |
| 17 | +# |
| 18 | +# References: |
| 19 | +# MDEV-25444: mysql --binary-mode is not able to replay some mysqlbinlog |
| 20 | +# outputs |
| 21 | + |
| 22 | +--echo # Note: This test assumes NO_BACKSLASH_ESCAPES is not set in SQL_MODE. |
| 23 | + |
| 24 | +--source include/have_log_bin.inc |
| 25 | + |
| 26 | +--echo ############################## |
| 27 | +--echo # Setup |
| 28 | +--echo ############################## |
| 29 | + |
| 30 | +--echo # |
| 31 | +--echo # Saving old state |
| 32 | +--echo # |
| 33 | +set @old_sql_mode= @@global.SQL_MODE; |
| 34 | +set @@global.SQL_MODE= ""; |
| 35 | + |
| 36 | +--echo # |
| 37 | +--echo # Create table for data entry |
| 38 | +--echo # |
| 39 | +CREATE TABLE tb (`id` int(11) NOT NULL AUTO_INCREMENT,`cb` longblob DEFAULT NULL, PRIMARY KEY (`id`)) AUTO_INCREMENT=1 DEFAULT CHARSET=latin1; |
| 40 | + |
| 41 | +# Will replay binlog later and we don't want to recreate the table |
| 42 | +RESET MASTER; |
| 43 | + |
| 44 | + |
| 45 | +--echo ############################## |
| 46 | +--echo # Test Case |
| 47 | +--echo ############################## |
| 48 | + |
| 49 | +--echo # |
| 50 | +--echo # \0 (0x5c00 in binary) should be allowed in data strings if |
| 51 | +--echo # --binary-mode is enabled. |
| 52 | +--echo # |
| 53 | +--perl |
| 54 | + my $dir= $ENV{'MYSQL_TMP_DIR'}; |
| 55 | + open (my $FILE, '>', "$dir/binary_zero_inserts.sql") or die "open(): $!"; |
| 56 | + |
| 57 | + print $FILE "TRUNCATE TABLE tb;\n"; |
| 58 | + |
| 59 | + # INSERT INTO tb(cb) VALUES(_binary '\0'); |
| 60 | + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; |
| 61 | + print $FILE pack "H*","5c00"; |
| 62 | + print $FILE "');\n"; |
| 63 | + |
| 64 | + # INSERT INTO tb(cb) VALUES(_binary '\0A'); |
| 65 | + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; |
| 66 | + print $FILE pack "H*","5c0041"; |
| 67 | + print $FILE "');\n"; |
| 68 | + |
| 69 | + # INSERT INTO tb(cb) VALUES(_binary 'A\0'); |
| 70 | + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; |
| 71 | + print $FILE pack "H*","415c00"; |
| 72 | + print $FILE "');\n"; |
| 73 | + |
| 74 | + # INSERT INTO tb(cb) VALUES(_binary 'A\0B'); |
| 75 | + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; |
| 76 | + print $FILE pack "H*","415c0042"; |
| 77 | + print $FILE "');\n"; |
| 78 | + |
| 79 | + # INSERT INTO tb(cb) VALUES(_binary '\0A\0'); |
| 80 | + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; |
| 81 | + print $FILE pack "H*","5c00415c00"; |
| 82 | + print $FILE "');\n"; |
| 83 | + |
| 84 | + # INSERT INTO tb(cb) VALUES(_binary '\\\0'); |
| 85 | + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; |
| 86 | + print $FILE pack "H*","5c5c5c00"; |
| 87 | + print $FILE "');\n"; |
| 88 | + |
| 89 | + # INSERT INTO tb(cb) VALUES(_binary '\0\0'); |
| 90 | + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; |
| 91 | + print $FILE pack "H*","5c005c00"; |
| 92 | + print $FILE "');\n"; |
| 93 | + |
| 94 | + # INSERT INTO tb(cb) VALUES(_binary '\\0'); |
| 95 | + print $FILE "INSERT INTO tb(cb) VALUES (_binary '"; |
| 96 | + print $FILE pack "H*","5c5c00"; |
| 97 | + print $FILE "');\n"; |
| 98 | + |
| 99 | + close ($FILE); |
| 100 | +EOF |
| 101 | +--let SEARCH_PATTERN= \x5c\x00 |
| 102 | +--let SEARCH_FILE= $MYSQL_TMP_DIR/binary_zero_inserts.sql |
| 103 | +--source include/search_pattern_in_file.inc |
| 104 | +--echo # MYSQL --binary-mode test < MYSQL_TMP_DIR/binary_zero_inserts.sql |
| 105 | +--exec $MYSQL --binary-mode test < $MYSQL_TMP_DIR/binary_zero_inserts.sql |
| 106 | + |
| 107 | +--echo # |
| 108 | +--echo # Ensure a row exists from each insert statement with a \0 |
| 109 | +--echo # |
| 110 | +SELECT COUNT(*)=8 from tb; |
| 111 | + |
| 112 | +--echo # |
| 113 | +--echo # Ensure that the binary zero was parsed and exists in the row data |
| 114 | +--echo # Note: We only look for 00 because the 5c only served as an escape |
| 115 | +--echo # in parsing. |
| 116 | +--echo # |
| 117 | +--echo # MYSQL_DUMP test tb --hex-blob | grep INSERT > MYSQL_TMP_DIR/dump.sql |
| 118 | +--exec $MYSQL_DUMP test tb --hex-blob | grep INSERT > $MYSQL_TMP_DIR/dump.sql |
| 119 | +--let SEARCH_PATTERN= 00 |
| 120 | +--let SEARCH_FILE= $MYSQL_TMP_DIR/dump.sql |
| 121 | +--source include/search_pattern_in_file.inc |
| 122 | + |
| 123 | +--echo # |
| 124 | +--echo # Ensure data consistency on mysqlbinlog replay |
| 125 | +--echo # |
| 126 | +--let $good_checksum= `CHECKSUM TABLE tb` |
| 127 | +let $MYSQLD_DATADIR= `SELECT @@datadir`; |
| 128 | +let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1); |
| 129 | +FLUSH LOGS; |
| 130 | +--echo # MYSQL_BINLOG MYSQLD_DATADIR/binlog_file > MYSQL_TMP_DIR/binlog_zeros.sql |
| 131 | +--exec $MYSQL_BINLOG $MYSQLD_DATADIR/$binlog_file > $MYSQL_TMP_DIR/binlog_zeros.sql |
| 132 | +--let SEARCH_PATTERN= \x5c\x00 |
| 133 | +--let SEARCH_FILE= $MYSQL_TMP_DIR/binlog_zeros.sql |
| 134 | +--source include/search_pattern_in_file.inc |
| 135 | +--echo # MYSQL --binary-mode test < MYSQL_TMP_DIR/binlog_zeros.sql |
| 136 | +--exec $MYSQL --binary-mode test < $MYSQL_TMP_DIR/binlog_zeros.sql |
| 137 | +if ($good_checksum != `CHECKSUM TABLE tb`) |
| 138 | +{ |
| 139 | + die "Blob with binary zero data changed after binary log replay"; |
| 140 | +} |
| 141 | +--echo # Table checksum is equivalent before and after binlog replay |
| 142 | + |
| 143 | +--echo # |
| 144 | +--echo # A \0 should still be treated as end-of-query in binary mode. |
| 145 | +--echo # |
| 146 | +--perl |
| 147 | + my $dir= $ENV{'MYSQL_TMP_DIR'}; |
| 148 | + open (my $FILE, '>', "$dir/binary_zero_eoq.sql") or die "open(): $!"; |
| 149 | + |
| 150 | + # INSERT INTO tb(cb) VALUES(_binary 'text')\0 |
| 151 | + print $FILE "INSERT INTO tb(cb) VALUES (_binary 'text')"; |
| 152 | + print $FILE pack "H*","5c00"; |
| 153 | + |
| 154 | + close ($FILE); |
| 155 | +EOF |
| 156 | +--echo # MYSQL --binary-mode -B test < MYSQL_TMP_DIR/binary_zero_eoq.sql |
| 157 | +--exec $MYSQL --binary-mode -B test < $MYSQL_TMP_DIR/binary_zero_eoq.sql |
| 158 | + |
| 159 | + |
| 160 | +--echo ############################## |
| 161 | +--echo # Cleanup |
| 162 | +--echo ############################## |
| 163 | + |
| 164 | +--remove_file $MYSQL_TMP_DIR/binary_zero_inserts.sql |
| 165 | +--remove_file $MYSQL_TMP_DIR/binary_zero_eoq.sql |
| 166 | +--remove_file $MYSQL_TMP_DIR/binlog_zeros.sql |
| 167 | +--remove_file $MYSQL_TMP_DIR/dump.sql |
| 168 | +SET @@global.sql_mode= @old_sql_mode; |
| 169 | +drop table tb; |
| 170 | +RESET MASTER; |
0 commit comments