Skip to content

Commit d4f740e

Browse files
committed
BUG29855733: Fix error during connection using charset and collation combination
An error is raised when using the combination of utf8mb4 as charset and utf8mb4_0900_bin as collation. The character id of this combination is 309, which is greater than 1 byte specified in the handshake protocol. This patch uses 1 extra byte from the reserved part of the payload, to accommodate the necessary 2 bytes of this combination. Tests were added/changed for regression.
1 parent 5632c58 commit d4f740e

File tree

4 files changed

+33
-8
lines changed

4 files changed

+33
-8
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ v8.0.17
1616
- WL#12735: Add README.rst and CONTRIBUTING.rst files
1717
- WL#12227: Indexing array fields
1818
- WL#12085: Support cursor prepared statements with C extension
19+
- BUG#29855733: Fix error during connection using charset and collation combination
1920
- BUG#29833590: Calling execute() should fetch active results
2021
- BUG#21072758: Support for connection attributes classic
2122

lib/mysql/connector/protocol.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,8 @@ def make_auth(self, handshake, username=None, password=None, database=None,
9898
except AttributeError:
9999
# Username is already bytes
100100
username_bytes = username
101-
packet = struct.pack('<IIB{filler}{usrlen}sx'.format(
102-
filler='x' * 23, usrlen=len(username_bytes)),
101+
packet = struct.pack('<IIH{filler}{usrlen}sx'.format(
102+
filler='x' * 22, usrlen=len(username_bytes)),
103103
client_flags, max_allowed_packet, charset,
104104
username_bytes)
105105

@@ -140,7 +140,7 @@ def make_auth_ssl(self, charset=45, client_flags=0,
140140
"""Make a SSL authentication packet"""
141141
return utils.int4store(client_flags) + \
142142
utils.int4store(max_allowed_packet) + \
143-
utils.int1store(charset) + \
143+
utils.int2store(charset) + \
144144
b'\x00' * 23
145145

146146
def make_command(self, command, argument=None):

tests/test_bugs.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5655,3 +5655,27 @@ def test_connection_args_compatibility(self):
56555655

56565656
cnx = self.cnx.__class__(**config)
56575657
cnx.close()
5658+
5659+
5660+
@unittest.skipIf(tests.MYSQL_VERSION < (8, 0, 17),
5661+
"MySQL 8.0.17+ is required for utf8mb4_0900_bin collation")
5662+
class BugOra29855733(tests.MySQLConnectorTests):
5663+
"""BUG#29855733: ERROR DURING THE CLASSIC CONNECTION WITH CHARSET AND
5664+
COLLATION SPECIFIED.
5665+
"""
5666+
def setUp(self):
5667+
pass
5668+
5669+
def tearDown(self):
5670+
pass
5671+
5672+
@foreach_cnx()
5673+
def test_connection_collation_utf8mb4_0900_bin(self):
5674+
config = self.config.copy()
5675+
config["username"] = config["user"]
5676+
config["passwd"] = config["password"]
5677+
config["charset"] = "utf8mb4"
5678+
config["collation"] = "utf8mb4_0900_bin"
5679+
5680+
cnx = self.cnx.__class__(**config)
5681+
cnx.close()

tests/test_protocol.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -139,20 +139,20 @@ def test_make_auth_ssl(self):
139139
({},
140140
b'\x00\x00\x00\x00\x00\x00\x00@-\x00\x00\x00\x00\x00\x00'
141141
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
142-
b'\x00\x00\x00'),
142+
b'\x00\x00\x00\x00'),
143143
({'charset': 8},
144-
b'\x00\x00\x00\x00\x00\x00\x00\x40\x08\x00\x00\x00\x00\x00'
144+
b'\x00\x00\x00\x00\x00\x00\x00@\x08\x00\x00\x00\x00\x00\x00'
145145
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
146146
b'\x00\x00\x00\x00'),
147147
({'client_flags': 240141},
148148
b'\r\xaa\x03\x00\x00\x00\x00@-\x00\x00\x00\x00\x00\x00\x00'
149149
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
150-
b'\x00\x00'),
150+
b'\x00\x00\x00'),
151151
({'charset': 8, 'client_flags': 240141,
152152
'max_allowed_packet': 2147483648},
153-
b'\x0d\xaa\x03\x00\x00\x00\x00\x80\x08\x00\x00\x00\x00\x00'
153+
b'\r\xaa\x03\x00\x00\x00\x00\x80\x08\x00\x00\x00\x00\x00'
154154
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
155-
b'\x00\x00\x00\x00'),
155+
b'\x00\x00\x00\x00\x00'),
156156
]
157157
for kwargs, exp in cases:
158158
self.assertEqual(exp, self._protocol.make_auth_ssl(**kwargs))

0 commit comments

Comments
 (0)