Skip to content

Commit 712af56

Browse files
committed
Merge branch 'release/2.1.5' into master-2.1
2 parents 60b283d + cb5d73b commit 712af56

File tree

8 files changed

+272
-39
lines changed

8 files changed

+272
-39
lines changed

CHANGES.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@ Copyright (c) 2009, 2016, Oracle and/or its affiliates. All rights reserved.
88
Full release notes:
99
http://dev.mysql.com/doc/relnotes/connector-python/en/
1010

11+
v2.1.5
12+
======
13+
14+
- BUG#25111218: Fix duplicate logic for reading EOF packet
15+
- BUG#21656282: Connection fails using unicode passwords with C extension
16+
- BUG#21530841: Select statement fails for results with more than 4096 columns
17+
- BUG#21530100: Fix reading option files
18+
- BUG#21477493: Fix RE_SQL_INSERT_STMT to correctly match Insert Statement
19+
- BUG#21476495: Fix set_charset_collation() for an invalid charset provided
20+
1121
v2.1.4
1222
======
1323

lib/mysql/connector/abstracts.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -634,7 +634,6 @@ def set_charset_collation(self, charset=None, collation=None):
634634
"""
635635
if charset:
636636
if isinstance(charset, int):
637-
self._charset_id = charset
638637
(self._charset_id, charset_name, collation_name) = \
639638
CharacterSet.get_charset_info(charset)
640639
elif isinstance(charset, str):

lib/mysql/connector/cursor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@
4040
r'''\s*ON\s+DUPLICATE\s+KEY(?:[^"'`]*["'`][^"'`]*["'`])*[^"'`]*$''',
4141
re.I | re.M | re.S)
4242
RE_SQL_INSERT_STMT = re.compile(
43-
r"({0}|\s)*INSERT({0}|\s)*INTO.+VALUES.*".format(SQL_COMMENT),
43+
r"({0}|\s)*INSERT({0}|\s)*INTO\s+[`'\"]?.+[`'\"]?(?:\.[`'\"]?.+[`'\"]?)"
44+
"{{0,2}}\s+VALUES\s*\(.+(?:\s*,.+)*\)".format(SQL_COMMENT),
4445
re.I | re.M | re.S)
4546
RE_SQL_INSERT_VALUES = re.compile(r'.*VALUES\s*(\(.*\)).*', re.I | re.M | re.S)
4647
RE_PY_PARAM = re.compile(b'(%s)')

lib/mysql/connector/optionfiles.py

Lines changed: 16 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -286,19 +286,19 @@ def get_groups(self, *args):
286286
args = self._options_dict.keys()
287287

288288
options = {}
289+
priority = {}
289290
for group in args:
290291
try:
291-
for option, value in self._options_dict[group].items():
292-
if option not in options or options[option][1] <= value[1]:
293-
options[option] = value
292+
for option, value in [(key, value,) for key, value in
293+
self._options_dict[group].items() if
294+
key != "__name__" and
295+
not key.startswith("!")]:
296+
if option not in options or priority[option] <= value[1]:
297+
priority[option] = value[1]
298+
options[option] = value[0]
294299
except KeyError:
295300
pass
296301

297-
for key in options.keys():
298-
if key == '__name__' or key.startswith('!'):
299-
del options[key]
300-
else:
301-
options[key] = options[key][0]
302302
return options
303303

304304
def get_groups_as_dict_with_priority(self, *args): # pylint: disable=C0103
@@ -321,14 +321,13 @@ def get_groups_as_dict_with_priority(self, *args): # pylint: disable=C0103
321321
options = dict()
322322
for group in args:
323323
try:
324-
options[group] = dict(self._options_dict[group])
324+
options[group] = dict((key, value,) for key, value in
325+
self._options_dict[group].items() if
326+
key != "__name__" and
327+
not key.startswith("!"))
325328
except KeyError:
326329
pass
327330

328-
for group in options.keys():
329-
for key in options[group].keys():
330-
if key == '__name__' or key.startswith('!'):
331-
del options[group][key]
332331
return options
333332

334333
def get_groups_as_dict(self, *args):
@@ -347,14 +346,11 @@ def get_groups_as_dict(self, *args):
347346
options = dict()
348347
for group in args:
349348
try:
350-
options[group] = dict(self._options_dict[group])
349+
options[group] = dict((key, value[0],) for key, value in
350+
self._options_dict[group].items() if
351+
key != "__name__" and
352+
not key.startswith("!"))
351353
except KeyError:
352354
pass
353355

354-
for group in options.keys():
355-
for key in options[group].keys():
356-
if key == '__name__' or key.startswith('!'):
357-
del options[group][key]
358-
else:
359-
options[group][key] = options[group][key][0]
360356
return options

lib/mysql/connector/protocol.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,6 @@ def parse_column_count(self, packet):
227227
"""Parse a MySQL packet with the number of columns in result set"""
228228
try:
229229
count = utils.read_lc_int(packet[4:])[1]
230-
if count > MAX_MYSQL_TABLE_COLUMNS:
231-
return None
232230
return count
233231
except (struct.error, ValueError):
234232
raise errors.InterfaceError("Failed parsing column count")
@@ -318,7 +316,6 @@ def read_text_result(self, sock, version, count=1):
318316
eof = None
319317
rowdata = None
320318
i = 0
321-
eof57 = version >= (5, 7, 5)
322319
while True:
323320
if eof or i == count:
324321
break
@@ -334,10 +331,6 @@ def read_text_result(self, sock, version, count=1):
334331
elif (packet[4] == 254 and packet[0] < 7):
335332
eof = self.parse_eof(packet)
336333
rowdata = None
337-
elif eof57 and (packet[4] == 0 and packet[0] > 9):
338-
# EOF deprecation: make sure we catch it whether flag is set or not
339-
eof = self.parse_ok(packet)
340-
rowdata = None
341334
else:
342335
eof = None
343336
rowdata = utils.read_lc_string_list(packet[4:])

lib/mysql/connector/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
as mysql.connector.version.
2727
"""
2828

29-
VERSION = (2, 1, 4, '', 0)
29+
VERSION = (2, 1, 5, '', 0)
3030

3131
if VERSION[3] and VERSION[4]:
3232
VERSION_TEXT = '{0}.{1}.{2}{3}{4}'.format(*VERSION)

src/mysql_capi.c

Lines changed: 38 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,14 +1025,16 @@ MySQL_commit(MySQL *self)
10251025
PyObject*
10261026
MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
10271027
{
1028-
char *host= NULL, *user= NULL, *password= NULL, *database= NULL,
1029-
*unix_socket= NULL;
1028+
char *host= NULL, *user= NULL, *database= NULL, *unix_socket= NULL;
10301029
char *ssl_ca= NULL, *ssl_cert= NULL, *ssl_key= NULL;
1031-
PyObject *charset_name, *compress, *ssl_verify_cert;
1030+
PyObject *charset_name, *compress, *ssl_verify_cert, *password;
10321031
const char* auth_plugin;
10331032
unsigned long client_flags= 0;
10341033
unsigned int port= 3306, tmp_uint;
10351034
unsigned int protocol= 0;
1035+
#if MYSQL_VERSION_ID >= 50711
1036+
unsigned int ssl_mode;
1037+
#endif
10361038
my_bool abool;
10371039
MYSQL *res;
10381040

@@ -1045,7 +1047,11 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
10451047
NULL
10461048
};
10471049

1050+
#ifdef PY3
10481051
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzzzkzkzzzO!O!", kwlist,
1052+
#else
1053+
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|zzOzkzkzzzO!O!", kwlist,
1054+
#endif
10491055
&host, &user, &password, &database,
10501056
&port, &unix_socket,
10511057
&client_flags,
@@ -1115,15 +1121,17 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
11151121
#endif
11161122
#if MYSQL_VERSION_ID >= 50711
11171123
{
1118-
mysql_options(&self->session, MYSQL_OPT_SSL_MODE, SSL_MODE_REQUIRED);
1124+
ssl_mode= SSL_MODE_REQUIRED;
1125+
mysql_options(&self->session, MYSQL_OPT_SSL_MODE, &ssl_mode);
11191126
}
11201127
#endif
11211128

11221129
if (ssl_verify_cert && ssl_verify_cert == Py_True)
11231130
{
11241131
#if MYSQL_VERSION_ID >= 50711
11251132
{
1126-
mysql_options(&self->session, MYSQL_OPT_SSL_MODE, SSL_MODE_VERIFY_IDENTITY);
1133+
ssl_mode= SSL_MODE_VERIFY_IDENTITY;
1134+
mysql_options(&self->session, MYSQL_OPT_SSL_MODE, &ssl_mode);
11271135
}
11281136
#else
11291137
{
@@ -1144,7 +1152,8 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
11441152
#endif
11451153
#if MYSQL_VERSION_ID >= 50711
11461154
{
1147-
mysql_options(&self->session, MYSQL_OPT_SSL_ENFORCE, SSL_MODE_DISABLED);
1155+
ssl_mode= SSL_MODE_DISABLED;
1156+
mysql_options(&self->session, MYSQL_OPT_SSL_MODE, &ssl_mode);
11481157
}
11491158
#endif
11501159
}
@@ -1170,9 +1179,29 @@ MySQL_connect(MySQL *self, PyObject *args, PyObject *kwds)
11701179
client_flags= client_flags & ~CLIENT_CONNECT_WITH_DB;
11711180
}
11721181

1173-
res= mysql_real_connect(&self->session,
1174-
host, user, password, database,
1175-
port, unix_socket, client_flags);
1182+
if (client_flags & CLIENT_LOCAL_FILES) {
1183+
abool= 1;
1184+
mysql_options(&self->session, MYSQL_OPT_LOCAL_INFILE, (unsigned int*)&abool);
1185+
}
1186+
1187+
#ifdef PY3
1188+
res= mysql_real_connect(&self->session, host, user, password, database,
1189+
port, unix_socket, client_flags);
1190+
#else
1191+
char* c_password;
1192+
if (PyUnicode_Check(password))
1193+
{
1194+
PyObject* u_password= PyUnicode_AsUTF8String(password);
1195+
c_password= PyString_AsString(u_password);
1196+
Py_DECREF(u_password);
1197+
}
1198+
else
1199+
{
1200+
c_password= PyString_AsString(password);
1201+
}
1202+
res= mysql_real_connect(&self->session, host, user, c_password, database,
1203+
port, unix_socket, client_flags);
1204+
#endif
11761205

11771206
Py_END_ALLOW_THREADS
11781207

0 commit comments

Comments
 (0)