Skip to content

Commit 7555f2b

Browse files
amitabnmariz
authored andcommitted
BUG25589496: Don't convert to unicode if non-ascii data is present
In Python 2.7, decoding utf-8 of binary data with non-ascii data is attempted, decode fails. To fix this error, we attempt to convert the entire mysql statement to unicode and pass it anyway incase it fails. Tests added for regression.
1 parent b449e46 commit 7555f2b

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

lib/mysql/connector/cursor.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,15 +103,20 @@ def replace(matchobj):
103103
if groups["conversion_type"] == b"%":
104104
value = b"%"
105105
if groups["conversion_type"] == b"s":
106-
key = groups["mapping_key"].encode("utf-8") \
107-
if PY2 else groups["mapping_key"]
106+
key = groups["mapping_key"]
108107
value = value_dict[key]
109108
if value is None:
110109
raise ValueError("Unsupported conversion_type: {0}"
111110
"".format(groups["conversion_type"]))
112-
return value.decode("utf-8") if PY2 else value
113-
return RE_PY_MAPPING_PARAM.sub(replace, bytestr.decode("utf-8")
114-
if PY2 else bytestr)
111+
return bytes(value) if PY2 else value
112+
113+
stmt = RE_PY_MAPPING_PARAM.sub(replace, bytestr)
114+
if PY2:
115+
try:
116+
return stmt.decode("utf-8")
117+
except UnicodeDecodeError:
118+
pass
119+
return stmt
115120

116121

117122
class CursorBase(MySQLCursorAbstract):

tests/test_bugs.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import traceback
4545
import time
4646
import unittest
47+
import pickle
4748

4849
import tests
4950
from tests import foreach_cnx, cnx_config
@@ -4305,3 +4306,39 @@ def test_cext_verify_server_certifcate(self):
43054306
mysql.connector.connect, **self.config)
43064307
self.config['ssl_verify_cert'] = False
43074308
mysql.connector.connect(**self.config)
4309+
4310+
4311+
class BugOra25589496(tests.MySQLConnectorTests):
4312+
"""BUG#25589496: COMMITS RELATED TO "BUG22529828" BROKE BINARY DATA
4313+
HANDLING FOR PYTHON 2.7
4314+
"""
4315+
def setUp(self):
4316+
config = tests.get_mysql_config()
4317+
self.cnx = connection.MySQLConnection(**config)
4318+
self.tbl = "Bug25589496"
4319+
self.cnx.cmd_query("DROP TABLE IF EXISTS {0}".format(self.tbl))
4320+
4321+
def tearDown(self):
4322+
self.cnx.cmd_query("DROP TABLE IF EXISTS {0}".format(self.tbl))
4323+
self.cnx.close()
4324+
4325+
def test_insert_binary(self):
4326+
table = """
4327+
CREATE TABLE {0} (
4328+
`id` int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
4329+
`section` VARCHAR(50) NOT NULL,
4330+
`pickled` LONGBLOB NOT NULL
4331+
)
4332+
""".format(self.tbl)
4333+
cursor = self.cnx.cursor()
4334+
cursor.execute(table)
4335+
4336+
pickled = pickle.dumps({'a': 'b'}, pickle.HIGHEST_PROTOCOL)
4337+
add_row_q = "INSERT INTO {0} (section, pickled) " \
4338+
"VALUES (%(section)s, %(pickled)s)".format(self.tbl)
4339+
4340+
new_row = cursor.execute(add_row_q, {'section': 'foo',
4341+
'pickled': pickled})
4342+
self.cnx.commit()
4343+
self.assertEqual(1, cursor.lastrowid)
4344+
cursor.close()

0 commit comments

Comments
 (0)