Skip to content

Commit f2bdae1

Browse files
committed
Fix for Bug#25554464, CONNECT FAILS WITH NPE WHEN THE SERVER STARTED
WITH CUSTOM COLLATION. Fix for Bug#100606 (31818423), UNECESARY CALL TO "SET NAMES 'UTF8' COLLATE 'UTF8_GENERAL_CI'".
1 parent 1177f29 commit f2bdae1

File tree

60 files changed

+1606
-1449
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1606
-1449
lines changed

CHANGES

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,11 @@
33

44
Version 8.0.26
55

6+
- Fix for Bug#25554464, CONNECT FAILS WITH NPE WHEN THE SERVER STARTED WITH CUSTOM COLLATION.
7+
8+
- Fix for Bug#100606 (31818423), UNECESARY CALL TO "SET NAMES 'UTF8' COLLATE 'UTF8_GENERAL_CI'".
9+
Thanks to Marc Fletcher for his contribution.
10+
611
- Fix for Bug#102404 (32435618), CONTRIBUTION: ADD TRACK SESSION STATE CHANGE.
712
Thanks to William Lee for his contribution.
813

src/main/core-api/java/com/mysql/cj/CharsetMapping.java

Lines changed: 155 additions & 189 deletions
Large diffs are not rendered by default.
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright (c) 2021, Oracle and/or its affiliates.
3+
*
4+
* This program is free software; you can redistribute it and/or modify it under
5+
* the terms of the GNU General Public License, version 2.0, as published by the
6+
* Free Software Foundation.
7+
*
8+
* This program is also distributed with certain software (including but not
9+
* limited to OpenSSL) that is licensed under separate terms, as designated in a
10+
* particular file or component or in included license documentation. The
11+
* authors of MySQL hereby grant you an additional permission to link the
12+
* program and your derivative works with the separately licensed software that
13+
* they have included with MySQL.
14+
*
15+
* Without limiting anything contained in the foregoing, this file, which is
16+
* part of MySQL Connector/J, is also subject to the Universal FOSS Exception,
17+
* version 1.0, a copy of which can be found at
18+
* http://oss.oracle.com/licenses/universal-foss-exception.
19+
*
20+
* This program is distributed in the hope that it will be useful, but WITHOUT
21+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
22+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
23+
* for more details.
24+
*
25+
* You should have received a copy of the GNU General Public License along with
26+
* this program; if not, write to the Free Software Foundation, Inc.,
27+
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
28+
*/
29+
30+
package com.mysql.cj;
31+
32+
public interface CharsetSettings {
33+
34+
public static final String CHARACTER_SET_CLIENT = "character_set_client";
35+
public static final String CHARACTER_SET_CONNECTION = "character_set_connection";
36+
public static final String CHARACTER_SET_RESULTS = "character_set_results";
37+
public static final String COLLATION_CONNECTION = "collation_connection";
38+
39+
/**
40+
* <p>
41+
* Choose the MySQL collation index for the handshake packet and the corresponding Java encodings for the password and error messages.
42+
* </p>
43+
* <p>
44+
* This index will be sent with HandshakeResponse setting server variables 'character_set_connection', 'collation_connection', 'character_set_client'
45+
* and 'character_set_results' which will be used by the server for decoding passwords during the authentication phase and later on, if
46+
* no SET NAMES are issued by {@link #configurePostHandshake(boolean)}.
47+
* </p>
48+
* <p>
49+
* It also means that collation index should be set according to:
50+
* <ol>
51+
* <li>'passwordCharacterEncoding' if it's present, or
52+
* <li>'connectionCollation' if it's present, or
53+
* <li>'characterEncoding' if it's present
54+
* </ol>
55+
* otherwise it will be set to utf8mb4_general_ci or utf8mb4_0900_ai_ci depending on server version.
56+
* <p>
57+
* Since Protocol::HandshakeV10 and Protocol::HandshakeResponse41 has only one byte for the collation it's not possible to use indexes &gt; 255 during the
58+
* handshake.
59+
* Also, ucs2, utf16, utf16le and utf32 character sets are impermissible here. Connector/J will try to use utf8mb4 instead.
60+
* </p>
61+
*
62+
* @param reset
63+
* reset the charsets configuration; needed for changeUser call.
64+
*
65+
* @return MySQL collation index to be used during the handshake.
66+
*/
67+
int configurePreHandshake(boolean reset);
68+
69+
/**
70+
* Sets up client character set. This must be done before any further communication with the server!
71+
*
72+
* The 'collation_connection', 'character_set_client', 'character_set_connection' and 'character_set_results' server variables are set
73+
* according to the collation index selected by {@link #configurePreHandshake(boolean)} and sent in the Protocol::HandshakeV10 packet.
74+
* Here Connector/J alters these server variables if needed.
75+
*
76+
* @param dontCheckServerMatch
77+
* if true then send the SET NAMES query even if server charset already matches the new value; needed for changeUser call.
78+
*/
79+
void configurePostHandshake(boolean dontCheckServerMatch);
80+
81+
public boolean doesPlatformDbCharsetMatches();
82+
83+
String getPasswordCharacterEncoding();
84+
85+
String getErrorMessageEncoding();
86+
87+
String getMetadataEncoding();
88+
89+
int getMetadataCollationIndex();
90+
91+
boolean getRequiresEscapingEncoder();
92+
93+
String getJavaEncodingForCollationIndex(int collationIndex);
94+
95+
int getMaxBytesPerChar(String javaCharsetName);
96+
97+
int getMaxBytesPerChar(Integer charsetIndex, String javaCharsetName);
98+
99+
Integer getCollationIndexForCollationName(String collationName);
100+
101+
String getCollationNameForCollationIndex(Integer collationIndex);
102+
103+
String getMysqlCharsetNameForCollationIndex(Integer collationIndex);
104+
105+
int getCollationIndexForJavaEncoding(String javaEncoding, ServerVersion version);
106+
107+
int getCollationIndexForMysqlCharsetName(String charsetName);
108+
109+
String getJavaEncodingForMysqlCharset(String mysqlCharsetName);
110+
111+
String getMysqlCharsetForJavaEncoding(String javaEncoding, ServerVersion version);
112+
113+
boolean isMultibyteCharset(String javaEncodingName);
114+
}

src/main/core-api/java/com/mysql/cj/Constants.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2002, 2020, Oracle and/or its affiliates.
2+
* Copyright (c) 2002, 2021, 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
@@ -96,6 +96,8 @@ public class Constants {
9696
public static final BigDecimal BIG_DECIMAL_MAX_FLOAT_VALUE = BigDecimal.valueOf(Float.MAX_VALUE);
9797
public static final BigDecimal BIG_DECIMAL_MAX_NEGATIVE_FLOAT_VALUE = BigDecimal.valueOf(-Float.MAX_VALUE);
9898

99+
public static final int UNSIGNED_BYTE_MAX_VALUE = 255;
100+
99101
/**
100102
* Prevents instantiation
101103
*/

src/main/core-api/java/com/mysql/cj/conf/PropertyDefinitions.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,9 @@ public enum DatabaseTerm {
259259
new StringPropertyDefinition(PropertyKey.characterSetResults, DEFAULT_VALUE_NULL_STRING, RUNTIME_MODIFIABLE,
260260
Messages.getString("ConnectionProperties.characterSetResults"), "3.0.13", CATEGORY_SESSION, Integer.MIN_VALUE),
261261

262+
new StringPropertyDefinition(PropertyKey.customCharsetMapping, DEFAULT_VALUE_NULL_STRING, RUNTIME_MODIFIABLE,
263+
Messages.getString("ConnectionProperties.customCharsetMapping"), "8.0.26", CATEGORY_SESSION, Integer.MIN_VALUE),
264+
262265
new StringPropertyDefinition(PropertyKey.connectionCollation, DEFAULT_VALUE_NULL_STRING, RUNTIME_MODIFIABLE,
263266
Messages.getString("ConnectionProperties.connectionCollation"), "3.0.13", CATEGORY_SESSION, Integer.MIN_VALUE),
264267

src/main/core-api/java/com/mysql/cj/conf/PropertyKey.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ public enum PropertyKey {
100100
connectTimeout("connectTimeout", true), //
101101
continueBatchOnError("continueBatchOnError", true), //
102102
createDatabaseIfNotExist("createDatabaseIfNotExist", true), //
103+
customCharsetMapping("customCharsetMapping", true), //
103104
databaseTerm("databaseTerm", true), //
104105
defaultAuthenticationPlugin("defaultAuthenticationPlugin", true), //
105106
defaultFetchSize("defaultFetchSize", true), //
Lines changed: 3 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2020, Oracle and/or its affiliates.
2+
* Copyright (c) 2015, 2021, 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
@@ -29,60 +29,24 @@
2929

3030
package com.mysql.cj.protocol;
3131

32-
import com.mysql.cj.CharsetMapping;
33-
import com.mysql.cj.Messages;
34-
import com.mysql.cj.ServerVersion;
3532
import com.mysql.cj.conf.PropertySet;
36-
import com.mysql.cj.exceptions.ExceptionFactory;
3733
import com.mysql.cj.exceptions.ExceptionInterceptor;
3834

3935
public interface AuthenticationProvider<M extends Message> {
4036

4137
void init(Protocol<M> prot, PropertySet propertySet, ExceptionInterceptor exceptionInterceptor);
4238

43-
void connect(ServerSession serverSession, String username, String password, String database);
39+
void connect(String username, String password, String database);
4440

4541
/**
4642
* Re-authenticates as the given user and password
4743
*
48-
* @param serverSession
49-
* {@link ServerSession} object
5044
* @param username
5145
* user name
5246
* @param password
5347
* password
5448
* @param database
5549
* db name
5650
*/
57-
void changeUser(ServerSession serverSession, String username, String password, String database);
58-
59-
String getEncodingForHandshake();
60-
61-
/**
62-
* Get the MySQL collation index for the handshake packet. A single byte will be added to the packet corresponding to the collation index
63-
* found for the requested Java encoding name.
64-
*
65-
* If the index is &gt; 255 which may be valid at some point in the future, an exception will be thrown. At the time of this implementation
66-
* the index cannot be &gt; 255 and only the COM_CHANGE_USER rpc, not the handshake response, can handle a value &gt; 255.
67-
*
68-
* @param enc
69-
* The Java encoding name used to lookup the collation index
70-
* @param sv
71-
* server version
72-
* @return collation index
73-
*/
74-
static byte getCharsetForHandshake(String enc, ServerVersion sv) {
75-
int charsetIndex = 0;
76-
if (enc != null) {
77-
charsetIndex = CharsetMapping.getCollationIndexForJavaEncoding(enc, sv);
78-
}
79-
if (charsetIndex == 0) {
80-
charsetIndex = CharsetMapping.MYSQL_COLLATION_INDEX_utf8;
81-
}
82-
if (charsetIndex > 255) {
83-
throw ExceptionFactory.createException(Messages.getString("MysqlIO.113", new Object[] { enc }));
84-
}
85-
return (byte) charsetIndex;
86-
}
87-
51+
void changeUser(String username, String password, String database);
8852
}

src/main/core-api/java/com/mysql/cj/protocol/Protocol.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2020, Oracle and/or its affiliates.
2+
* Copyright (c) 2015, 2021, 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
@@ -127,8 +127,6 @@ public interface Protocol<M extends Message> {
127127
*/
128128
void changeUser(String user, String password, String database);
129129

130-
String getPasswordCharacterEncoding();
131-
132130
boolean versionMeetsMinimum(int major, int minor, int subminor);
133131

134132
/**

src/main/core-api/java/com/mysql/cj/protocol/ServerCapabilities.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2015, 2020, Oracle and/or its affiliates.
2+
* Copyright (c) 2015, 2021, 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
@@ -42,8 +42,11 @@ public interface ServerCapabilities {
4242

4343
ServerVersion getServerVersion();
4444

45-
void setServerVersion(ServerVersion serverVersion);
45+
long getThreadId();
46+
47+
void setThreadId(long threadId);
4648

4749
boolean serverSupportsFracSecs();
4850

51+
int getServerDefaultCollationIndex();
4952
}

src/main/core-api/java/com/mysql/cj/protocol/ServerSession.java

Lines changed: 4 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import java.util.Map;
3333
import java.util.TimeZone;
3434

35+
import com.mysql.cj.CharsetSettings;
3536
import com.mysql.cj.ServerVersion;
3637
import com.mysql.cj.exceptions.CJOperationNotSupportedException;
3738
import com.mysql.cj.exceptions.ExceptionFactory;
@@ -62,8 +63,6 @@ public interface ServerSession {
6263
*/
6364
public static int TRANSACTION_COMPLETED = 3;
6465

65-
public static final String LOCAL_CHARACTER_SET_RESULTS = "local.character_set_results";
66-
6766
ServerCapabilities getCapabilities();
6867

6968
void setCapabilities(ServerCapabilities capabilities);
@@ -92,20 +91,6 @@ public interface ServerSession {
9291

9392
void setOldStatusFlags(int statusFlags);
9493

95-
/**
96-
*
97-
* @return Collation index which server provided in handshake greeting packet
98-
*/
99-
int getServerDefaultCollationIndex();
100-
101-
/**
102-
* Stores collation index which server provided in handshake greeting packet.
103-
*
104-
* @param serverDefaultCollationIndex
105-
* collation index
106-
*/
107-
void setServerDefaultCollationIndex(int serverDefaultCollationIndex);
108-
10994
/**
11095
*
11196
* @return TRANSACTION_NOT_STARTED, TRANSACTION_IN_PROGRESS, TRANSACTION_STARTED or TRANSACTION_COMPLETED
@@ -153,8 +138,6 @@ public interface ServerSession {
153138

154139
void setServerVariables(Map<String, String> serverVariables);
155140

156-
boolean characterSetNamesMatches(String mysqlEncodingName);
157-
158141
/**
159142
* Get the version of the MySQL server we are talking to.
160143
*
@@ -174,46 +157,6 @@ public interface ServerSession {
174157
*/
175158
boolean isVersion(ServerVersion version);
176159

177-
/**
178-
*
179-
* @return the server's default character set name according to collation index from server greeting,
180-
* or value of 'character_set_server' variable if there is no mapping for that index
181-
*/
182-
String getServerDefaultCharset();
183-
184-
String getErrorMessageEncoding();
185-
186-
void setErrorMessageEncoding(String errorMessageEncoding);
187-
188-
int getMaxBytesPerChar(String javaCharsetName);
189-
190-
int getMaxBytesPerChar(Integer charsetIndex, String javaCharsetName);
191-
192-
/**
193-
* Returns the Java character encoding name for the given MySQL server
194-
* collation index
195-
*
196-
* @param collationIndex
197-
* collation index
198-
* @return the Java character encoding name for the given MySQL server
199-
* collation index
200-
*/
201-
String getEncodingForIndex(int collationIndex);
202-
203-
void configureCharacterSets();
204-
205-
String getCharacterSetMetadata();
206-
207-
void setCharacterSetMetadata(String characterSetMetadata);
208-
209-
int getMetadataCollationIndex();
210-
211-
void setMetadataCollationIndex(int metadataCollationIndex);
212-
213-
String getCharacterSetResultsOnServer();
214-
215-
void setCharacterSetResultsOnServer(String characterSetResultsOnServer);
216-
217160
/**
218161
* Is the server configured to use lower-case table names only?
219162
*
@@ -231,10 +174,6 @@ public interface ServerSession {
231174

232175
public boolean isServerTruncatesFracSecs();
233176

234-
long getThreadId();
235-
236-
public void setThreadId(long threadId);
237-
238177
boolean isAutoCommit();
239178

240179
void setAutoCommit(boolean autoCommit);
@@ -255,4 +194,7 @@ default ServerSessionStateController getServerSessionStateController() {
255194
throw ExceptionFactory.createException(CJOperationNotSupportedException.class, "Not supported");
256195
}
257196

197+
CharsetSettings getCharsetSettings();
198+
199+
void setCharsetSettings(CharsetSettings charsetSettings);
258200
}

0 commit comments

Comments
 (0)