Skip to content

Commit 69ab3b2

Browse files
committed
Merge branch 'release/3.1.2'
2 parents 8ae1292 + 2f3ca1b commit 69ab3b2

File tree

13 files changed

+139
-71
lines changed

13 files changed

+139
-71
lines changed

.travis.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ install:
3333
connector-test-machine/launch.bat -t "$srv" -v "$v" -d testj
3434
;;
3535
linux)
36-
source connector-test-machine/launch.sh -t "$srv" -v "$v" -d testj -n 0 -l "$local" -p "$packet"
36+
source connector-test-machine/launch.sh -t "$srv" -v "$v" -d testj -l "$local" -p "$packet"
3737
;;
3838
esac
3939

CHANGELOG.md

+15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,19 @@
11
# Change Log
2+
3+
## [3.1.2](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.1.2) (Jan 2023)
4+
[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.1.1...3.1.2)
5+
6+
* CONJ-1040 possible ConcurrentModificationException when connecting
7+
* CONJ-1041 possible ArrayIndexOutOfBoundsException
8+
9+
## [2.7.8](https://github.com/mariadb-corporation/mariadb-connector-j/tree/2.7.8) (Jan 2023)
10+
[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/2.7.7...2.7.8)
11+
12+
* CONJ-1039 setQueryTimeout not honored by CallableStatement for procedures depending on security context
13+
* CONJ-1041 possible ArrayIndexOutOfBoundsException
14+
* CONJ-1023 set missing SSL capability in handshake after SSL exchanges
15+
16+
217
## [3.1.1](https://github.com/mariadb-corporation/mariadb-connector-j/tree/3.1.1) (Jan 2023)
318
[Full Changelog](https://github.com/mariadb-corporation/mariadb-connector-j/compare/3.1.0...3.1.1)
419

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ or maven :
2626
<dependency>
2727
<groupId>org.mariadb.jdbc</groupId>
2828
<artifactId>mariadb-java-client</artifactId>
29-
<version>3.1.1</version>
29+
<version>3.1.2</version>
3030
</dependency>
3131
```
3232

@@ -45,7 +45,7 @@ Development snapshot are available on sonatype nexus repository
4545
<dependency>
4646
<groupId>org.mariadb.jdbc</groupId>
4747
<artifactId>mariadb-java-client</artifactId>
48-
<version>3.1.2-SNAPSHOT</version>
48+
<version>3.1.3-SNAPSHOT</version>
4949
</dependency>
5050
</dependencies>
5151
```

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
<artifactId>mariadb-java-client</artifactId>
88
<packaging>jar</packaging>
99
<name>mariadb-java-client</name>
10-
<version>3.1.1</version>
10+
<version>3.1.2</version>
1111
<description>JDBC driver for MariaDB and MySQL</description>
1212
<url>https://mariadb.com/kb/en/mariadb/about-mariadb-connector-j/</url>
1313

src/main/java/org/mariadb/jdbc/Configuration.java

+10-17
Original file line numberDiff line numberDiff line change
@@ -617,21 +617,17 @@ private static void mapPropertiesToOption(Builder builder, Properties properties
617617
// loop on properties,
618618
// - check DefaultOption to check that property value correspond to type (and range)
619619
// - set values
620-
Properties remainingProperties = new Properties();
621-
properties.forEach((key, val) -> remainingProperties.put(key, val));
622-
623-
for (Field field : Builder.class.getDeclaredFields()) {
624-
if (remainingProperties.isEmpty()) break;
625-
for (final Object keyObj : remainingProperties.keySet()) {
626-
String realKey =
627-
OptionAliases.OPTIONS_ALIASES.get(keyObj.toString().toLowerCase(Locale.ROOT));
628-
if (realKey == null) realKey = keyObj.toString();
629-
final Object propertyValue = remainingProperties.get(keyObj);
630-
631-
if (propertyValue != null && realKey != null) {
620+
for (final Object keyObj : properties.keySet()) {
621+
String realKey =
622+
OptionAliases.OPTIONS_ALIASES.get(keyObj.toString().toLowerCase(Locale.ROOT));
623+
if (realKey == null) realKey = keyObj.toString();
624+
final Object propertyValue = properties.get(keyObj);
625+
if (propertyValue != null && realKey != null) {
626+
boolean used = false;
627+
for (Field field : Builder.class.getDeclaredFields()) {
632628
if (realKey.toLowerCase(Locale.ROOT).equals(field.getName().toLowerCase(Locale.ROOT))) {
633629
field.setAccessible(true);
634-
remainingProperties.remove(keyObj);
630+
used = true;
635631

636632
if (field.getGenericType().equals(String.class)
637633
&& !propertyValue.toString().isEmpty()) {
@@ -668,13 +664,10 @@ private static void mapPropertiesToOption(Builder builder, Properties properties
668664
}
669665
}
670666
}
667+
if (!used) nonMappedOptions.put(realKey, propertyValue);
671668
}
672669
}
673670

674-
// keep unknown option:
675-
// those might be used in authentication or identity plugin
676-
remainingProperties.forEach((key, val) -> nonMappedOptions.put(key, val));
677-
678671
// for compatibility with 2.x
679672
if (isSet("useSsl", nonMappedOptions) || isSet("useSSL", nonMappedOptions)) {
680673
Properties deprecatedDesc = new Properties();

src/main/java/org/mariadb/jdbc/DatabaseMetaData.java

+55-37
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import java.text.ParseException;
1010
import java.util.*;
1111
import org.mariadb.jdbc.client.DataType;
12+
import org.mariadb.jdbc.client.ServerVersion;
1213
import org.mariadb.jdbc.client.result.CompleteResult;
1314
import org.mariadb.jdbc.client.result.Result;
1415
import org.mariadb.jdbc.util.VersionFactory;
@@ -823,43 +824,60 @@ public ResultSet getColumns(
823824
String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
824825
throws SQLException {
825826

826-
StringBuilder sb =
827-
new StringBuilder(
828-
"SELECT TABLE_SCHEMA TABLE_CAT, NULL TABLE_SCHEM, TABLE_NAME, COLUMN_NAME,"
829-
+ dataTypeClause("COLUMN_TYPE")
830-
+ " DATA_TYPE,"
831-
+ DataTypeClause(conf)
832-
+ " TYPE_NAME, "
833-
+ " CASE DATA_TYPE"
834-
+ " WHEN 'time' THEN "
835-
+ "IF(DATETIME_PRECISION = 0, 10, CAST(11 + DATETIME_PRECISION as signed integer))"
836-
+ " WHEN 'date' THEN 10"
837-
+ " WHEN 'datetime' THEN "
838-
+ "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))"
839-
+ " WHEN 'timestamp' THEN "
840-
+ "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))"
841-
+ (conf.yearIsDateType() ? "" : " WHEN 'year' THEN 5")
842-
+ " ELSE "
843-
+ " IF(NUMERIC_PRECISION IS NULL, LEAST(CHARACTER_MAXIMUM_LENGTH,"
844-
+ Integer.MAX_VALUE
845-
+ "), NUMERIC_PRECISION) "
846-
+ " END"
847-
+ " COLUMN_SIZE, 65535 BUFFER_LENGTH, "
848-
+ " CONVERT (CASE DATA_TYPE"
849-
+ " WHEN 'year' THEN "
850-
+ (conf.yearIsDateType() ? "NUMERIC_SCALE" : "0")
851-
+ " WHEN 'tinyint' THEN "
852-
+ (conf.tinyInt1isBit() ? "0" : "NUMERIC_SCALE")
853-
+ " ELSE NUMERIC_SCALE END, UNSIGNED INTEGER) DECIMAL_DIGITS,"
854-
+ " 10 NUM_PREC_RADIX, IF(IS_NULLABLE = 'yes',1,0) NULLABLE,COLUMN_COMMENT REMARKS,"
855-
+ " COLUMN_DEFAULT COLUMN_DEF, 0 SQL_DATA_TYPE, 0 SQL_DATETIME_SUB, "
856-
+ " LEAST(CHARACTER_OCTET_LENGTH,"
857-
+ Integer.MAX_VALUE
858-
+ ") CHAR_OCTET_LENGTH,"
859-
+ " ORDINAL_POSITION, IS_NULLABLE, NULL SCOPE_CATALOG, NULL SCOPE_SCHEMA, NULL SCOPE_TABLE, NULL SOURCE_DATA_TYPE,"
860-
+ " IF(EXTRA = 'auto_increment','YES','NO') IS_AUTOINCREMENT, "
861-
+ " IF(EXTRA in ('VIRTUAL', 'PERSISTENT', 'VIRTUAL GENERATED', 'STORED GENERATED') ,'YES','NO') IS_GENERATEDCOLUMN "
862-
+ " FROM INFORMATION_SCHEMA.COLUMNS");
827+
ServerVersion version = connection.getContext().getVersion();
828+
boolean supportsFractionalSeconds =
829+
version.isMariaDBServer()
830+
/* "In MariaDB 5.3 and later, the TIME, DATETIME, and TIMESTAMP types, along with the temporal
831+
functions, CAST and dynamic columns, now support microseconds."
832+
https://web.archive.org/web/20130928042640/https://mariadb.com/kb/en/microseconds-in-mariadb/
833+
*/
834+
? version.versionGreaterOrEqual(5, 3, 0)
835+
// See https://dev.mysql.com/doc/relnotes/mysql/5.6/en/news-5-6-4.html
836+
: version.versionGreaterOrEqual(5, 6, 4);
837+
StringBuilder sb = new StringBuilder();
838+
sb.append(
839+
"SELECT TABLE_SCHEMA TABLE_CAT, NULL TABLE_SCHEM, TABLE_NAME, COLUMN_NAME,"
840+
+ dataTypeClause("COLUMN_TYPE")
841+
+ " DATA_TYPE,"
842+
+ DataTypeClause(conf)
843+
+ " TYPE_NAME, "
844+
+ " CASE DATA_TYPE"
845+
+ " WHEN 'date' THEN 10");
846+
if (supportsFractionalSeconds) {
847+
sb.append(
848+
" WHEN 'time' THEN "
849+
+ "IF(DATETIME_PRECISION = 0, 10, CAST(11 + DATETIME_PRECISION as signed integer))"
850+
+ " WHEN 'datetime' THEN "
851+
+ "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))"
852+
+ " WHEN 'timestamp' THEN "
853+
+ "IF(DATETIME_PRECISION = 0, 19, CAST(20 + DATETIME_PRECISION as signed integer))");
854+
} else {
855+
// Older versions do not include the DATETIME_PRECISION column in INFORMATION_SCHEMA.COLUMNS.
856+
sb.append(" WHEN 'time' THEN 10 WHEN 'datetime' THEN 19 WHEN 'timestamp' THEN 19");
857+
}
858+
sb.append(
859+
(conf.yearIsDateType() ? "" : " WHEN 'year' THEN 5")
860+
+ " ELSE "
861+
+ " IF(NUMERIC_PRECISION IS NULL, LEAST(CHARACTER_MAXIMUM_LENGTH,"
862+
+ Integer.MAX_VALUE
863+
+ "), NUMERIC_PRECISION) "
864+
+ " END"
865+
+ " COLUMN_SIZE, 65535 BUFFER_LENGTH, "
866+
+ " CONVERT (CASE DATA_TYPE"
867+
+ " WHEN 'year' THEN "
868+
+ (conf.yearIsDateType() ? "NUMERIC_SCALE" : "0")
869+
+ " WHEN 'tinyint' THEN "
870+
+ (conf.tinyInt1isBit() ? "0" : "NUMERIC_SCALE")
871+
+ " ELSE NUMERIC_SCALE END, UNSIGNED INTEGER) DECIMAL_DIGITS,"
872+
+ " 10 NUM_PREC_RADIX, IF(IS_NULLABLE = 'yes',1,0) NULLABLE,COLUMN_COMMENT REMARKS,"
873+
+ " COLUMN_DEFAULT COLUMN_DEF, 0 SQL_DATA_TYPE, 0 SQL_DATETIME_SUB, "
874+
+ " LEAST(CHARACTER_OCTET_LENGTH,"
875+
+ Integer.MAX_VALUE
876+
+ ") CHAR_OCTET_LENGTH,"
877+
+ " ORDINAL_POSITION, IS_NULLABLE, NULL SCOPE_CATALOG, NULL SCOPE_SCHEMA, NULL SCOPE_TABLE, NULL SOURCE_DATA_TYPE,"
878+
+ " IF(EXTRA = 'auto_increment','YES','NO') IS_AUTOINCREMENT, "
879+
+ " IF(EXTRA in ('VIRTUAL', 'PERSISTENT', 'VIRTUAL GENERATED', 'STORED GENERATED') ,'YES','NO') IS_GENERATEDCOLUMN "
880+
+ " FROM INFORMATION_SCHEMA.COLUMNS");
863881
boolean firstCondition = catalogCond(true, sb, "TABLE_SCHEMA", catalog);
864882
firstCondition = patternCond(firstCondition, sb, "TABLE_NAME", tableNamePattern);
865883
firstCondition = patternCond(firstCondition, sb, "COLUMN_NAME", columnNamePattern);

src/main/java/org/mariadb/jdbc/client/socket/impl/PacketWriter.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -561,8 +561,10 @@ public void writeBytesEscaped(byte[] bytes, int len, boolean noBackslashEscapes)
561561
}
562562

563563
} else {
564-
565564
// not enough space in buf, will fill buf
565+
if (buf.length <= pos) {
566+
writeSocket(false);
567+
}
566568
if (noBackslashEscapes) {
567569
for (int i = 0; i < len; i++) {
568570
if (QUOTE == bytes[i]) {

src/main/java/org/mariadb/jdbc/plugin/authentication/standard/CachingSha2PasswordPlugin.java

+5-1
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,11 @@ public ReadableByteBuf process(Writer out, Reader in, Context context)
134134
// retrieve public key from configuration or from server
135135
PublicKey publicKey;
136136
if (conf.serverRsaPublicKeyFile() != null) {
137-
publicKey = readPublicKeyFromFile(conf.serverRsaPublicKeyFile());
137+
if (conf.serverRsaPublicKeyFile().contains("BEGIN PUBLIC KEY")) {
138+
publicKey = generatePublicKey(conf.serverRsaPublicKeyFile().getBytes());
139+
} else {
140+
publicKey = readPublicKeyFromFile(conf.serverRsaPublicKeyFile());
141+
}
138142
} else {
139143
// read public key from socket
140144
if (!conf.allowPublicKeyRetrieval()) {

src/main/java/org/mariadb/jdbc/util/VersionFactory.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,11 @@ public static Version getInstance() {
2121
Version.class.getClassLoader().getResourceAsStream("mariadb.properties")) {
2222
if (inputStream == null) {
2323
System.out.println("property file 'mariadb.properties' not found in the classpath");
24+
} else {
25+
Properties prop = new Properties();
26+
prop.load(inputStream);
27+
tmpVersion = prop.getProperty("version");
2428
}
25-
Properties prop = new Properties();
26-
prop.load(inputStream);
27-
tmpVersion = prop.getProperty("version");
2829
} catch (IOException e) {
2930
e.printStackTrace();
3031
}

src/test/java/org/mariadb/jdbc/integration/ConnectionTest.java

+10-3
Original file line numberDiff line numberDiff line change
@@ -993,9 +993,16 @@ public void localSocket() throws Exception {
993993
} catch (SQLException e) {
994994
// eat
995995
}
996-
997-
stmt.execute("CREATE USER testSocket IDENTIFIED BY 'heyPassw!µ20§rd'");
998-
stmt.execute("GRANT SELECT on *.* to testSocket IDENTIFIED BY 'heyPassw!µ20§rd'");
996+
boolean useOldNotation =
997+
(!isMariaDBServer() || !minVersion(10, 2, 0))
998+
&& (isMariaDBServer() || !minVersion(8, 0, 0));
999+
if (useOldNotation) {
1000+
stmt.execute("CREATE USER testSocket IDENTIFIED BY 'heyPassw!µ20§rd'");
1001+
stmt.execute("GRANT SELECT on *.* to testSocket IDENTIFIED BY 'heyPassw!µ20§rd'");
1002+
} else {
1003+
stmt.execute("CREATE USER testSocket IDENTIFIED BY 'heyPassw!µ20§rd'");
1004+
stmt.execute("GRANT SELECT on *.* to testSocket");
1005+
}
9991006
// mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
10001007
Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
10011008
stmt.execute("FLUSH PRIVILEGES");

src/test/java/org/mariadb/jdbc/integration/Sha256AuthenticationTest.java

+15-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ public class Sha256AuthenticationTest extends Common {
1515

1616
private static void dropUserWithoutError(org.mariadb.jdbc.Statement stmt, String user) {
1717
try {
18-
stmt.execute("DROP USER " + user);
18+
stmt.execute("DROP USER IF EXISTS " + user);
1919
} catch (SQLException e) {
2020
// eat
2121
}
@@ -65,6 +65,17 @@ public static void init() throws Exception {
6565
rsaPublicKey = checkFileExists("../../ssl/public.key");
6666
}
6767

68+
if (rsaPublicKey == null) {
69+
ResultSet rs = stmt.executeQuery("SHOW STATUS like 'Caching_sha2_password_rsa_public_key'");
70+
rs.next();
71+
rsaPublicKey = rs.getString(2);
72+
if ("".equals(rsaPublicKey)) rsaPublicKey = null;
73+
if (rsaPublicKey != null) {
74+
System.out.println(
75+
"rsaPublicKey set from @@Caching_sha2_password_rsa_public_key:" + rsaPublicKey);
76+
}
77+
}
78+
6879
stmt.execute(
6980
"CREATE USER 'cachingSha256User'@'%' IDENTIFIED WITH caching_sha2_password BY '!Passw0rd3Works'");
7081
stmt.execute(
@@ -126,7 +137,7 @@ public void cachingSha256Empty() throws Exception {
126137
Assumptions.assumeTrue(
127138
!isWindows() && !isMariaDBServer() && rsaPublicKey != null && minVersion(8, 0, 0));
128139
// mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
129-
Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
140+
Assumptions.assumeTrue(!isMariaDBServer() && !minVersion(8, 0, 31));
130141
sharedConn.createStatement().execute("FLUSH PRIVILEGES"); // reset cache
131142
try (Connection con = createCon("user=cachingSha256User2&allowPublicKeyRetrieval&password=")) {
132143
con.isValid(1);
@@ -155,7 +166,7 @@ public void wrongRsaPath() throws Exception {
155166
public void cachingSha256Allow() throws Exception {
156167
Assumptions.assumeTrue(!isMariaDBServer() && rsaPublicKey != null && minVersion(8, 0, 0));
157168
// mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
158-
Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
169+
Assumptions.assumeTrue(!isMariaDBServer() && !minVersion(8, 0, 31));
159170
sharedConn.createStatement().execute("FLUSH PRIVILEGES"); // reset cache
160171
try (Connection con =
161172
createCon("user=cachingSha256User3&allowPublicKeyRetrieval&password=!Passw0rd3Works")) {
@@ -205,7 +216,7 @@ public void cachingSha256PluginTest() throws Exception {
205216
public void cachingSha256PluginTestWithoutServerRsaKey() throws Exception {
206217
Assumptions.assumeTrue(!isWindows() && minVersion(8, 0, 0));
207218
// mysql 8.0.31 broken public key retrieval, so avoid FLUSHING for now
208-
Assumptions.assumeTrue(!isMariaDBServer() && !exactVersion(8, 0, 31));
219+
Assumptions.assumeTrue(!isMariaDBServer() && !minVersion(8, 0, 31));
209220
sharedConn.createStatement().execute("FLUSH PRIVILEGES"); // reset cache
210221
try (Connection con =
211222
createCon("user=cachingSha256User&password=!Passw0rd3Works&allowPublicKeyRetrieval")) {

src/test/java/org/mariadb/jdbc/unit/client/socket/PackerWriterTest.java src/test/java/org/mariadb/jdbc/unit/client/socket/PacketWriterTest.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import org.junit.jupiter.api.Test;
66
import org.mariadb.jdbc.client.socket.impl.PacketWriter;
77

8-
public class PackerWriterTest {
8+
public class PacketWriterTest {
99

1010
@Test
1111
public void growBuffer() throws IOException {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.mariadb.jdbc.unit.util;
2+
3+
import static org.junit.jupiter.api.Assertions.assertNotNull;
4+
5+
import org.junit.jupiter.api.Test;
6+
import org.mariadb.jdbc.util.Version;
7+
import org.mariadb.jdbc.util.VersionFactory;
8+
9+
class VersionFactoryTest {
10+
11+
@Test
12+
public void testGetInstance() {
13+
Version actual = VersionFactory.getInstance();
14+
15+
assertNotNull(actual);
16+
}
17+
}

0 commit comments

Comments
 (0)