Skip to content

Commit be9f8f0

Browse files
committed
Fix for Bug#34558945, PS using setCharacterStream() fails with "Incorrect string value" if the Java program encoding is not UTF-8 after 8.0.29.
Change-Id: Ic6f0c33c312b79869263c6717b9d033cc92d5c12
1 parent bbe2c6b commit be9f8f0

File tree

3 files changed

+99
-4
lines changed

3 files changed

+99
-4
lines changed

CHANGES

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
Version 8.0.33
55

6+
- Fix for Bug#34558945, PS using setCharacterStream() fails with "Incorrect string value" if the Java program encoding is not UTF-8 after 8.0.29.
7+
68
- Fix for Bug#109013 (Bug#34772608), useServerPrepStmts and useLocalTransactionState could cause rollback failure.
79

810
- Fix for bug Bug#108643 (Bug#34652568), Commit statement not effect when two params turns on.

src/main/protocol-impl/java/com/mysql/cj/protocol/a/ReaderValueEncoder.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, Oracle and/or its affiliates.
2+
* Copyright (c) 2022, 2023, Oracle and/or its affiliates.
33
*
44
* This program is free software; you can redistribute it and/or modify it under
55
* the terms of the GNU General Public License, version 2.0, as published by the
@@ -66,20 +66,23 @@ protected byte[] readBytes(Reader reader, BindValue binding) {
6666
byte[] bytes;
6767

6868
boolean useLength = this.propertySet.getBooleanProperty(PropertyKey.useStreamLengthsInPrepStmts).getValue();
69-
String forcedEncoding = binding.isNational() ? null : this.propertySet.getStringProperty(PropertyKey.clobCharacterEncoding).getStringValue();
69+
String clobEncoding = binding.isNational() ? null : this.propertySet.getStringProperty(PropertyKey.clobCharacterEncoding).getStringValue();
70+
if (clobEncoding == null) {
71+
clobEncoding = this.charEncoding.getStringValue();
72+
}
7073

7174
long scaleOrLength = binding.getScaleOrLength();
7275
if (useLength && (scaleOrLength != -1)) {
7376
c = new char[(int) scaleOrLength];
7477
int numCharsRead = Util.readFully(reader, c, (int) scaleOrLength); // blocks until all read
75-
bytes = StringUtils.getBytes(new String(c, 0, numCharsRead), forcedEncoding);
78+
bytes = StringUtils.getBytes(new String(c, 0, numCharsRead), clobEncoding);
7679
} else {
7780
c = new char[4096];
7881
StringBuilder buf = new StringBuilder();
7982
while ((len = reader.read(c)) != -1) {
8083
buf.append(c, 0, len);
8184
}
82-
bytes = StringUtils.getBytes(buf.toString(), forcedEncoding);
85+
bytes = StringUtils.getBytes(buf.toString(), clobEncoding);
8386
}
8487
return escapeBytesIfNeeded(bytes);
8588

src/test/java/testsuite/regression/StatementRegressionTest.java

+90
Original file line numberDiff line numberDiff line change
@@ -13160,4 +13160,94 @@ public <T extends Resultset> T preProcess(Supplier<String> sql, Query intercepte
1316013160
return super.preProcess(sql, interceptedQuery);
1316113161
}
1316213162
}
13163+
13164+
/**
13165+
* Tests fix for Bug#34558945, PS using setCharacterStream() fails with "Incorrect string value" if the Java program encoding is not UTF-8 after 8.0.29.
13166+
*
13167+
* @throws Exception
13168+
*/
13169+
@Test
13170+
void testBug34558945() throws Exception {
13171+
createTable("testBug34558945Utf8", "(txt VARCHAR(100) COLLATE utf8mb4_0900_ai_ci)");
13172+
createTable("testBug34558945SJis", "(txt VARCHAR(100) COLLATE sjis_japanese_ci)");
13173+
13174+
Properties props = new Properties();
13175+
props.setProperty(PropertyKey.sslMode.getKeyName(), SslMode.DISABLED.name());
13176+
props.setProperty(PropertyKey.allowPublicKeyRetrieval.getKeyName(), "true");
13177+
13178+
final String utf8 = "UTF-8";
13179+
final String sjis = "Shift_JIS";
13180+
final String[] charEncs = { null, utf8, sjis };
13181+
final String value = "\u7ADC";
13182+
13183+
for (String ce : charEncs) {
13184+
for (String cce : charEncs) {
13185+
13186+
if (ce == null) {
13187+
props.remove(PropertyKey.characterEncoding.getKeyName());
13188+
} else {
13189+
props.setProperty(PropertyKey.characterEncoding.getKeyName(), ce);
13190+
}
13191+
if (cce == null) {
13192+
props.remove(PropertyKey.clobCharacterEncoding.getKeyName());
13193+
} else {
13194+
props.setProperty(PropertyKey.clobCharacterEncoding.getKeyName(), cce);
13195+
}
13196+
13197+
boolean useSPS = false;
13198+
do {
13199+
props.setProperty(PropertyKey.useServerPrepStmts.getKeyName(), Boolean.toString(useSPS));
13200+
try (Connection testConn = getConnectionWithProps(props)) {
13201+
int records;
13202+
PreparedStatement testPStmt;
13203+
Statement testStmt;
13204+
13205+
// Table with UTF-8 column.
13206+
records = 1;
13207+
testPStmt = testConn.prepareStatement("INSERT INTO testBug34558945Utf8 VALUES (?)");
13208+
testPStmt.setString(1, value);
13209+
assertEquals(1, testPStmt.executeUpdate());
13210+
testPStmt.setCharacterStream(1, new StringReader(value), value.length());
13211+
if (sjis.equals(cce) || cce == null && sjis.equals(ce)) {
13212+
assertThrows(SQLException.class, ".*Incorrect string value:.*", testPStmt::executeUpdate);
13213+
} else {
13214+
assertEquals(1, testPStmt.executeUpdate());
13215+
records = 2;
13216+
}
13217+
13218+
testStmt = testConn.createStatement();
13219+
this.rs = testStmt.executeQuery("SELECT * FROM testBug34558945Utf8");
13220+
while (records-- > 0) {
13221+
assertTrue(this.rs.next());
13222+
assertEquals(value, this.rs.getString(1));
13223+
}
13224+
assertFalse(this.rs.next());
13225+
testStmt.executeUpdate("TRUNCATE TABLE testBug34558945Utf8");
13226+
13227+
// Table with Shift_JIS column.
13228+
records = 1;
13229+
testPStmt = testConn.prepareStatement("INSERT INTO testBug34558945SJis VALUES (?)");
13230+
testPStmt.setString(1, value);
13231+
assertEquals(1, testPStmt.executeUpdate());
13232+
testPStmt.setCharacterStream(1, new StringReader(value), value.length());
13233+
if (sjis.equals(cce) || cce == null && sjis.equals(ce)) {
13234+
assertEquals(1, testPStmt.executeUpdate());
13235+
records = 2;
13236+
} else {
13237+
assertThrows(SQLException.class, ".*Incorrect string value:.*", testPStmt::executeUpdate);
13238+
}
13239+
13240+
testStmt = testConn.createStatement();
13241+
this.rs = testStmt.executeQuery("SELECT * FROM testBug34558945SJis");
13242+
while (records-- > 0) {
13243+
assertTrue(this.rs.next());
13244+
assertEquals(value, this.rs.getString(1));
13245+
}
13246+
assertFalse(this.rs.next());
13247+
testStmt.executeUpdate("TRUNCATE TABLE testBug34558945SJis");
13248+
}
13249+
} while (useSPS = !useSPS);
13250+
}
13251+
}
13252+
}
1316313253
}

0 commit comments

Comments
 (0)