Bug #11338 | logging of prepared statement w/ blob type | ||
---|---|---|---|
Submitted: | 15 Jun 2005 4:55 | Modified: | 24 Aug 2005 17:59 |
Reporter: | Timothy Smith | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Replication | Severity: | S2 (Serious) |
Version: | 4.1.12, 5.0.9 | OS: | Any (any) |
Assigned to: | Elliot Murphy | CPU Architecture: | Any |
[15 Jun 2005 4:55]
Timothy Smith
[29 Jun 2005 1:09]
Timothy Smith
I just tested this against the latest MySQL 5.0 code from BK. The bug happens there as well. I used a java test program this time, to ensure that I am doing the exact same steps as the reporting user. A summary of my results is: The behavior in MySQL 5.0 is identical to that of MySQL 4.1. In both cases, it is not enough to use the same character set with the server and the client. The problem comes because, in cp932, characters between 0x81 and 0x9f introduce a multi-byte sequence. So when the character string '?\0' (where ? == 0x83) is read in the cp932 character set, ?\ becomes one character, and 0 becomes a second. The '\0' escape sequence is never seen. This problem could affect any multi-byte character set. Now, here is my testing. I have added this to my [mysqld] section: character_set_server = cp932 Then I run the following Java program (it does the same basically as my C program, but it sets the character set in the URL): ============================================= 12:57 ~/m/50/m/t$ mysql --default-character-set=cp932 -e 'drop table if exists btable; create table btable (f1 blob); show create table btable\G' test *************************** 1. row *************************** Table: btable Create Table: CREATE TABLE `btable` ( `f1` blob ) ENGINE=InnoDB DEFAULT CHARSET=cp932 12:57 ~/m/50/m/t$ mysql -e 'show master status;' +-----------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +-----------------+----------+--------------+------------------+ | siva-bin.000001 | 1144 | | | +-----------------+----------+--------------+------------------+ 12:57 ~/m/50/m/t$ java -classpath $HOME/m/java/mysql-connector-java-3.1.10/mysql-connector-java-3.1.10-bin.jar:. JDBC2 12:57 ~/m/50/m/t$ mysql --default-character-set=cp932 -e 'select hex(f1) from btable' test +---------+ | hex(f1) | +---------+ | 8300 | +---------+ 12:58 ~/m/50/m/t$ mysqlbinlog --start-position=1144 ../data/siva-bin.000001 /*!40019 SET @@session.max_insert_delayed_threads=0*/; /*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; # at 1144 #050629 12:57:57 server id 33500 end_log_pos 95 Query thread_id=11 exec_time=0 error_code=0 use test; SET TIMESTAMP=1120006677; SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=1, @@session.unique_checks=1; SET @@session.sql_mode=0; SET @@session.character_set_client=95,@@session.collation_connection=95,@@session.collation_server=95; INSERT INTO btable VALUES('�\0'); # at 1239 #050629 12:57:57 server id 33500 end_log_pos 1266 Xid = 61 COMMIT; ROLLBACK; /*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; 12:58 ~/m/50/m/t$ mysqlbinlog --start-position=1144 ../data/siva-bin.000001 | grep INSERT | xxd 0000000: 494e 5345 5254 2049 4e54 4f20 6274 6162 INSERT INTO btab 0000010: 6c65 2056 414c 5545 5328 2783 5c30 2729 le VALUES('.\0') 0000020: 3b0a ;. 12:58 ~/m/50/m/t$ mysqlbinlog --start-position=1144 ../data/siva-bin.000001 | mysql --default-character-set=cp932 test 12:59 ~/m/50/m/t$ mysql --default-character-set=cp932 -e 'select hex(f1) from btable' test +---------+ | hex(f1) | +---------+ | 8300 | | 835C30 | +---------+ 12:59 ~/m/50/m/t$ mysql --default-character-set=cp932 -e 'show variables like "version%"' +-------------------------+----------------------+ | Variable_name | Value | +-------------------------+----------------------+ | version | 5.0.9-beta-debug-log | | version_comment | Source distribution | | version_compile_machine | i386 | | version_compile_os | unknown-freebsd5.4 | +-------------------------+----------------------+ ============================================= Here is the Java test program, called JDBC2.java: ============================================= import java.sql.*; public class JDBC2 { public static void main(String[] args) throws Exception{ Connection conn = null; PreparedStatement pstmt = null; ResultSet rs = null; Statement stmt; Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:33500/test?" + "user=root&password=&characterEncoding=CP932"); stmt = conn.createStatement(); byte[] data = new byte[2]; data[0] = (byte)0x83; data[1] = (byte)0x00; pstmt = conn.prepareStatement("INSERT INTO btable VALUES(?)"); pstmt.setBytes(1,data); pstmt.executeUpdate(); } } =============================================
[25 Jul 2005 21:08]
Elliot Murphy
Per discussion with Bar, unsafe bytes are codes less than 0x20, more than 0x7F, also 0x22 (quot), 0x27(apostroph), 0x5C(slash). Other bytes should be safe.
[17 Aug 2005 8:26]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/internals/28372
[17 Aug 2005 8:31]
Elliot Murphy
Reviewed by Konstantin, fix also discussed extensively with Bar.
[17 Aug 2005 10:20]
Elliot Murphy
Thank you for your bug report. This issue has been committed to our source repository of that product and will be incorporated into the next release. If necessary, you can access the source repository and build the latest available version, including the bugfix, yourself. More information about accessing the source trees is available at http://www.mysql.com/doc/en/Installing_source_tree.html Additional info: The fix was to encode parameters to prepared statements in hex before inserting into binlog when cp932 is used as the client charset. This fix has been pushed for 4.1.14, will set to documenting when I have merged to 5.0
[18 Aug 2005 18:46]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/internals/28472
[20 Aug 2005 4:23]
Elliot Murphy
The fix was to hex encode the parameters to a prepared statement before writing them into the binary log if the client was connected using cp932. This fix went into 4.1.14 and has been pushed for 5.0.12.
[24 Aug 2005 17:58]
Mike Hillyer
Documented in 4.1.14 and 5.0.12 changelogs: <listitem><para>Prepared statement parameters could cause errors in the binary log if the character set was <literal>cp932</literal>. (Bug #11338)</para></listitem>