| Bug #64731 | StringUtils.getBytesWrapped throws StringIndexOutOfBoundsException | ||
|---|---|---|---|
| Submitted: | 22 Mar 2012 7:01 | Modified: | 20 Jun 2012 21:46 |
| Reporter: | zhang jinyan | Email Updates: | |
| Status: | Closed | Impact on me: | |
| Category: | Connector / J | Severity: | S2 (Serious) |
| Version: | 5.1.18 | OS: | Any |
| Assigned to: | Alexander Soklakov | CPU Architecture: | Any |
| Tags: | getBytesWrapped, StringIndexOutOfBoundsException, StringUtils | ||
[22 Mar 2012 16:18]
zhang jinyan
Fix code should be:
StringBuffer buf = new StringBuffer(s.length() + 2);
buf.append(beginWrap);
buf.append(s);
buf.append(endWrap);
s = buf.toString();// fix code
b = s.getBytes(encoding);// fix code
if (!parserKnowsUnicode && (encoding.equalsIgnoreCase("SJIS") //$NON-NLS-1$
|| encoding.equalsIgnoreCase("BIG5") //$NON-NLS-1$
|| encoding.equalsIgnoreCase("GBK"))) { //$NON-NLS-1$
if (!encoding.equalsIgnoreCase(serverEncoding)) {
b = escapeEasternUnicodeByteStream(b, s, 0, s.length());
}
}
[10 Apr 2012 8:22]
Alexander Soklakov
Verified as described.
[20 Jun 2012 21:46]
John Russell
Added to changelog for 5.1.21: With a connection encoding of gbk and a server encoding of latin1, a call such as PreparedStatement.setString(1, "0f0f0702") could thrown an exception java.lang.StringIndexOutOfBoundsException.

Description: When connection encoding is "gbk", server encoding is "latin1"。 Use PreparedStatement.setString(1, "0f0f0702"),exception will be thrown: Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 8 at java.lang.String.charAt(String.java:686) at com.mysql.jdbc.StringUtils.escapeEasternUnicodeByteStream(StringUtils.java:231) at com.mysql.jdbc.StringUtils.getBytesWrapped(StringUtils.java:575) How to repeat: Test case: byte[] data = StringUtils.getBytesWrapped("0f0f0702", '\'', '\'',null, "gbk", "latin1", false, null); System.out.println(Arrays.toString(data)); Suggested fix: mysql-connector-java-5.1.18 StringUtils.java(line 595~609): StringBuffer buf = new StringBuffer(s.length() + 2); buf.append(beginWrap); buf.append(s); buf.append(endWrap); b = buf.toString().getBytes(encoding); if (!parserKnowsUnicode && (encoding.equalsIgnoreCase("SJIS") //$NON-NLS-1$ || encoding.equalsIgnoreCase("BIG5") //$NON-NLS-1$ || encoding.equalsIgnoreCase("GBK"))) { //$NON-NLS-1$ if (!encoding.equalsIgnoreCase(serverEncoding)) { b = escapeEasternUnicodeByteStream(b, s, 0, s.length()); } } When invoke escapeEasternUnicodeByteStream(b, s, 0, s.length()); variable b is not the corresponding byte[] for string variable s。 Fix code: b = s.getBytes(encoding); if (!parserKnowsUnicode && (encoding.equalsIgnoreCase("SJIS") //$NON-NLS-1$ || encoding.equalsIgnoreCase("BIG5") //$NON-NLS-1$ || encoding.equalsIgnoreCase("GBK"))) { //$NON-NLS-1$ if (!encoding.equalsIgnoreCase(serverEncoding)) { b = StringUtils.escapeEasternUnicodeByteStream(b, s, 0, s.length()); } } StringBuffer buf = new StringBuffer(s.length() + 2); buf.append(beginWrap); buf.append(s); buf.append(endWrap); b = buf.toString().getBytes(encoding);