| Bug #84586 | getConnection will failed if ConnectionAttributes is large than 255 | ||
|---|---|---|---|
| Submitted: | 20 Jan 2017 13:40 | Modified: | 20 Jan 2022 10:46 |
| Reporter: | cai feiji | Email Updates: | |
| Status: | Can't repeat | Impact on me: | |
| Category: | Connector / J | Severity: | S3 (Non-critical) |
| Version: | 5.1.30, 5.1.40 | OS: | Any |
| Assigned to: | CPU Architecture: | Any | |
| Tags: | ConnectionAttributes | ||
[23 Jan 2017 12:38]
Chiranjeevi Battula
Hello Feizhi Cai, Thank you for the bug report. I tried to reproduce the issue at my end using MySQL Connector / J 5.1.40 and MySQL 5.7.17 but not seeing any issues in ConnectionAttributes is large than 255. Could you please provide us repeatable test case (steps, sample code, full stack trace etc. - please make it as private if you prefer) to confirm this issue at our end? Thanks, Chiranjeevi.
[23 Jan 2017 12:53]
cai feiji
As shown above, the connection attributes can be set by user.
if a user set the connection attributes (it happened in my project), the whole length of connection attributes may be larger than 255.
You can use this code, to generate a connection attribute large than 255:
String url = String.format("jdbc:mysql://%s/%s?connectionAttributes=", addr, databaseName);
String key = "key";
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 255; ++i) {
builder.append("v");
}
String value = builder.toString();
url += key + ":" + value;
connection = DriverManager.getConnection(url, username, password) ;
You need to specify addr,databaseName,username,password yourself.
[23 Jan 2017 13:00]
Chiranjeevi Battula
Hello Feizhi Cai, Thank you for the feedback. I could not repeat the issue at my end using your test case with MySQL Connector / J 5.1.40 and MySQL 5.7.17 version. Thanks, Chiranjeevi.
[23 Jan 2017 13:46]
cai feiji
It seems mysql 5.7 will no disconnect while the connection attribute is not correct(but in my db(Compatible with the mysql protocol), this will cause a SQLException).
So I wrote another code to show this:
String urlBase = String.format("jdbc:mysql://%s/%s?connectionAttributes=", proxyAddr, databaseName);
String key = "key";
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 255; ++i) {
builder.append("v");
}
String value = builder.toString();
String shortUrl = urlBase + key + ":" + "value";
String longUrl = urlBase + key + ":" + value;
Connection connection = DriverManager.getConnection(shortUrl, username, password) ;
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery("select * from performance_schema.session_connect_attrs;");
boolean foundShortValue = false;
while (rs.next()) {
if (rs.getString("ATTR_NAME").equals(key)) {
foundShortValue = true;
}
}
rs.close();
connection.close();
boolean foundLongValue = false;
connection = DriverManager.getConnection(longUrl, username, password) ;
stmt = connection.createStatement();
rs = stmt.executeQuery("select * from performance_schema.session_connect_attrs;");
while (rs.next()) {
if (rs.getString("ATTR_NAME").equals(key)) {
foundLongValue = true;
}
}
rs.close();
connection.close();
System.out.println("foundShortValue = " + foundShortValue + ", foundLongValue = " + foundLongValue);
The output will be:
foundShortValue = true, foundLongValue = false
So if the connection attribute is large than 255, the user defined attribute will miss;
[24 Jan 2017 10:21]
Chiranjeevi Battula
Hello Feizhi Cai, Thank you for the feedback and test case. Verified this behavior on MySQL Connector / J 5.1.40. Thanks, Chiranjeevi.
[20 Jan 2022 10:46]
Alexander Soklakov
Posted by developer: This bug is not reproducible with the latest Connector/J 8.0. Connector/J 5.1 series came to EOL on Feb 9th, 2021, see https://www.mysql.com/support/eol-notice.html, so this bug will not be fixed there.

Description: if user-defined ConnectionAttributes length is large than 255(actually less than this length, as mysql-connector-j defined its ConnectionAttributes ), connector will failed to getConnection How to repeat: String url = String.format("jdbc:mysql://%s/%s?connectionAttributes=", proxyAddr, databaseName); String key = "k1"; StringBuilder builder = new StringBuilder(); for (int i = 0; i < 255; ++i) { builder.append("v"); } String value = builder.toString(); url += key + ":" + value; Connection connection = null; try { connection = DriverManager.getConnection(url, username, password) ; } catch (Exception e) { System.out.println("oooooooops"); } Suggested fix: the code in connector/J MysqlIo.java sendConnectionAttributes function: String atts = conn.getConnectionAttributes(); Buffer lb = new Buffer(100); try { Properties props = getConnectionAttributesAsProperties(atts); for (Object key : props.keySet()) { lb.writeLenString((String) key, enc, conn.getServerCharset(), null, conn.parserKnowsUnicode(), conn); lb.writeLenString(props.getProperty((String) key), enc, conn.getServerCharset(), null, conn.parserKnowsUnicode(), conn); } } catch (UnsupportedEncodingException e) { } buf.writeByte((byte) (lb.getPosition() - 4)); buf.writeBytesNoNull(lb.getByteBuffer(), 4, lb.getBufLength() - 4); if (lb.getPosition() - 4) is larger than a byte(255), the buf length written in the first byte is incorrect