Bug #2313 #879 still exists in v3.0.9
Submitted: 7 Jan 2004 21:53 Modified: 13 Jan 2004 13:38
Reporter: [ name withheld ] Email Updates:
Status: Duplicate Impact on me:
None 
Category:Connector / J Severity:S1 (Critical)
Version:3.0.9 OS:perhaps for all os
Assigned to: CPU Architecture:Any

[7 Jan 2004 21:53] [ name withheld ]
Description:
The situation described by bug #879 still exists in the new stable version 3.0.9.
In StringUtils.java, method escapeSJISByteStream(), the only change I can find different from previous bugy version is the codes that will be processed when loByte == 0x5c. I don't understand what the code hereinafter means, and how it can be used to eliminate the "double escaping" bug:

if (hiByte == 0x62) {
    // we need to escape the 0x5c
    bytesOut.write(0x5c);
    bytesOut.write(0x62);
    bufIndex++;
}

In fact, this version has solved the problem introduced by the scratch code in bug #879, i.e. the codes in bug #879 has now worked properly in GBK environment. But unfortunately, it doesn't solve the real problem, when the string delivered to PreparedStatement.setString() is a real GBK encoded character stream, rather than a single-byte string in the test program.

How to repeat:
Almost same as what bug 879 shows, except for the test string. The string in setString() is tow multi-byte characters and a single quote (') next to them without any space.

Create a database (we use test in this case) with GBK charset, and then create a
table:
create table test(col varchar(200));

Write a java program testjdbc.java:
import java.sql.*;
                                                                                
                                          
public class testjdbc
{
        public static void main(String[] args)
                throws Exception
        {
                try {
                        Class.forName("com.mysql.jdbc.Driver").newInstance();
                        Connection con =
DriverManager.getConnection("jdbc:mysql://localhost:3306/test?user=jdbc&password
=jdbc");
                       
                        PreparedStatement pstmt = con.prepareStatement("insert
into test(col) values(?)");
                        pstmt.setString(1, "试验'");
                        pstmt.executeUpdate();
                        pstmt.close();
                        con.close();
                } catch (SQLException e) {
                        System.out.println(e.getSQLState() + ":" +
e.getErrorCode());
                        throw e;
                }
        }
}

Compile and run it, and you'll get the error.

Suggested fix:
Don't use escapeSJISByteStream() for GBK and Big5 encoding.
[13 Jan 2004 13:38] Mark Matthews
Duplicate of #879