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.