Skip to content

Commit

Permalink
BUG29855733: Fix error during connection using charset and collation …
Browse files Browse the repository at this point in the history
…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.
  • Loading branch information
nmariz committed Jun 5, 2019
1 parent 5632c58 commit d4f740e
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGES.txt
Expand Up @@ -16,6 +16,7 @@ v8.0.17
- WL#12735: Add README.rst and CONTRIBUTING.rst files
- WL#12227: Indexing array fields
- WL#12085: Support cursor prepared statements with C extension
- BUG#29855733: Fix error during connection using charset and collation combination
- BUG#29833590: Calling execute() should fetch active results
- BUG#21072758: Support for connection attributes classic

Expand Down
6 changes: 3 additions & 3 deletions lib/mysql/connector/protocol.py
Expand Up @@ -98,8 +98,8 @@ def make_auth(self, handshake, username=None, password=None, database=None,
except AttributeError:
# Username is already bytes
username_bytes = username
packet = struct.pack('<IIB{filler}{usrlen}sx'.format(
filler='x' * 23, usrlen=len(username_bytes)),
packet = struct.pack('<IIH{filler}{usrlen}sx'.format(
filler='x' * 22, usrlen=len(username_bytes)),
client_flags, max_allowed_packet, charset,
username_bytes)

Expand Down Expand Up @@ -140,7 +140,7 @@ def make_auth_ssl(self, charset=45, client_flags=0,
"""Make a SSL authentication packet"""
return utils.int4store(client_flags) + \
utils.int4store(max_allowed_packet) + \
utils.int1store(charset) + \
utils.int2store(charset) + \
b'\x00' * 23

def make_command(self, command, argument=None):
Expand Down
24 changes: 24 additions & 0 deletions tests/test_bugs.py
Expand Up @@ -5655,3 +5655,27 @@ def test_connection_args_compatibility(self):

cnx = self.cnx.__class__(**config)
cnx.close()


@unittest.skipIf(tests.MYSQL_VERSION < (8, 0, 17),
"MySQL 8.0.17+ is required for utf8mb4_0900_bin collation")
class BugOra29855733(tests.MySQLConnectorTests):
"""BUG#29855733: ERROR DURING THE CLASSIC CONNECTION WITH CHARSET AND
COLLATION SPECIFIED.
"""
def setUp(self):
pass

def tearDown(self):
pass

@foreach_cnx()
def test_connection_collation_utf8mb4_0900_bin(self):
config = self.config.copy()
config["username"] = config["user"]
config["passwd"] = config["password"]
config["charset"] = "utf8mb4"
config["collation"] = "utf8mb4_0900_bin"

cnx = self.cnx.__class__(**config)
cnx.close()
10 changes: 5 additions & 5 deletions tests/test_protocol.py
Expand Up @@ -139,20 +139,20 @@ def test_make_auth_ssl(self):
({},
b'\x00\x00\x00\x00\x00\x00\x00@-\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00'),
b'\x00\x00\x00\x00'),
({'charset': 8},
b'\x00\x00\x00\x00\x00\x00\x00\x40\x08\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00@\x08\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00'),
({'client_flags': 240141},
b'\r\xaa\x03\x00\x00\x00\x00@-\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00'),
b'\x00\x00\x00'),
({'charset': 8, 'client_flags': 240141,
'max_allowed_packet': 2147483648},
b'\x0d\xaa\x03\x00\x00\x00\x00\x80\x08\x00\x00\x00\x00\x00'
b'\r\xaa\x03\x00\x00\x00\x00\x80\x08\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
b'\x00\x00\x00\x00'),
b'\x00\x00\x00\x00\x00'),
]
for kwargs, exp in cases:
self.assertEqual(exp, self._protocol.make_auth_ssl(**kwargs))
Expand Down

0 comments on commit d4f740e

Please sign in to comment.