Skip to content

Commit 9b86b29

Browse files
committed
BUG#37859771 - mysql/connector python version 9.3.0 has a regression
which cannot persist binary data with percent signs in it Reverted back the changes made to fix BUG#37447394 which introduced an unwanted behavior reducing double percentage sign character "%%s" in query strings passed to MySQLCursor.execute to a single "%s" character. Change-Id: I8fd834e8f165827672a272f30d410191880a6e8a
1 parent 83a5d24 commit 9b86b29

File tree

6 files changed

+338
-66
lines changed

6 files changed

+338
-66
lines changed

CHANGES.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ v9.4.0
1616
- WL#16962: Update the Python Protobuf version
1717
- BUG#37868219: RPM packages have incorrect copyright year in their metadata
1818
- BUG#37820231: Text based django ORM filters doesn't work with Connector/Python
19+
- BUG#37859771: mysql/connector python version 9.3.0 has a regression which cannot persist binary data with percent signs in it
1920
- BUG#37806057: Rename extra option (when installing wheel package) to install webauthn functionality dependencies
2021
- BUG#37642447: The license type is missing from RPM package
2122
- BUG#37627508: mysql/connector python fetchmany() has an off by one bug when argument given as 1
@@ -32,7 +33,6 @@ v9.3.0
3233
- WL#16327: Remove Cursors Prepared Raw and Named Tuple
3334
- BUG#37541353: (Contribution) Fix typing annotation of MySQLConnectionAbstract's close function
3435
- BUG#37453587: Github links in PyPI project's pages do not work
35-
- BUG#37447394: Unable to escape a parameter marker (`%s`) used in a query that should not be treated as a parameter marker
3636
- BUG#37418436: Arbitrary File Read in MySQL Python Client library
3737
- BUG#37410052: Bad formatting of exceptions when connecting with Unix sockets
3838
- BUG#37399636: The C-extension has a memory leak when working with prepared statements

mysql-connector-python/lib/mysql/connector/aio/cursor.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,6 @@ async def _prepare_statement(
410410
f"Could not process parameters: {type(params).__name__}({params}),"
411411
" it must be of type list, tuple or dict"
412412
)
413-
# final statement with `%%s` should be replaced as `%s`
414-
stmt = stmt.replace(b"%%s", b"%s")
415413

416414
return stmt
417415

@@ -1209,8 +1207,6 @@ async def execute(
12091207
except UnicodeEncodeError as err:
12101208
raise ProgrammingError(str(err)) from err
12111209

1212-
# final statement with `%%s` should be replaced as `%s`
1213-
operation = operation.replace(b"%%s", b"%s")
12141210
if b"%s" in operation:
12151211
# Convert %s to ? before sending it to MySQL
12161212
operation = re.sub(RE_SQL_FIND_PARAM, b"?", operation)

mysql-connector-python/lib/mysql/connector/cursor.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@
9595
re.I | re.M | re.S,
9696
)
9797
RE_SQL_INSERT_VALUES = re.compile(r".*VALUES\s*(\(.+\)).*", re.I | re.M | re.S)
98-
RE_PY_PARAM = re.compile(b"((?<!%)%s)")
98+
RE_PY_PARAM = re.compile(b"(%s)")
9999
RE_PY_MAPPING_PARAM = re.compile(
100100
rb"""
101101
%
@@ -400,8 +400,6 @@ def execute(
400400
" it must be of type list, tuple or dict"
401401
)
402402

403-
# final statement with `%%s` should be replaced as `%s`
404-
stmt = stmt.replace(b"%%s", b"%s")
405403
self._stmt_partitions = split_multi_statement(
406404
sql_code=stmt, map_results=map_results
407405
)
@@ -1237,8 +1235,6 @@ def execute(
12371235
except UnicodeEncodeError as err:
12381236
raise ProgrammingError(str(err)) from err
12391237

1240-
# final statement with `%%s` should be replaced as `%s`
1241-
operation = operation.replace(b"%%s", b"%s")
12421238
if b"%s" in operation:
12431239
# Convert %s to ? before sending it to MySQL
12441240
operation = re.sub(RE_SQL_FIND_PARAM, b"?", operation)

mysql-connector-python/lib/mysql/connector/cursor_cext.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -336,9 +336,6 @@ def execute(
336336
"Not all parameters were used in the SQL statement"
337337
)
338338

339-
# final statement with `%%s` should be replaced as `%s`
340-
stmt = stmt.replace(b"%%s", b"%s")
341-
342339
self._stmt_partitions = split_multi_statement(
343340
sql_code=stmt, map_results=map_results
344341
)
@@ -1129,8 +1126,6 @@ def execute(
11291126
except UnicodeDecodeError as err:
11301127
raise ProgrammingError(str(err)) from err
11311128

1132-
# final statement with `%%s` should be replaced as `%s`
1133-
operation = operation.replace("%%s", "%s")
11341129
if isinstance(params, dict):
11351130
replacement_keys = re.findall(RE_SQL_PYTHON_CAPTURE_PARAM_NAME, operation)
11361131
try:

mysql-connector-python/tests/test_bugs.py

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -8900,57 +8900,6 @@ def test_connection_timeout(self):
89008900
self.fail(err)
89018901

89028902

8903-
class BugOra37447394(tests.MySQLConnectorTests):
8904-
"""BUG#37447394: Unable to escape a parameter marker (`%s`) used in a query that should not be
8905-
treated as a parameter marker.
8906-
8907-
The `%s` parameter marker is not being escaped by using `%%s` in an SQL statement being passed
8908-
via the cursor's execute() method. This is required while passing a query like:
8909-
`select date_format(%s, "%Y-%m-%d %H:%i:%%s")`. Currently, the `%s` at the end of the query is
8910-
is not being escaped and is being treated like a parameter marker instead.
8911-
8912-
This patch fixes this issue by adding proper regular expression checks to escape the `%s` by
8913-
using `%%s`.
8914-
"""
8915-
8916-
stmt = 'select date_format(%s, "%Y-%m-%d %H:%i:%%s")'
8917-
params = ("2017-06-15 12:20:23",)
8918-
8919-
@foreach_cnx()
8920-
def test_bug37447394(self):
8921-
try:
8922-
with self.cnx.cursor() as cur:
8923-
cur.execute(self.stmt, self.params)
8924-
self.assertEqual(cur.fetchone(), self.params)
8925-
with self.cnx.cursor(prepared=True) as cur:
8926-
cur.execute(self.stmt, self.params)
8927-
self.assertEqual(cur.fetchone(), self.params)
8928-
except Exception as err:
8929-
self.fail(err)
8930-
8931-
8932-
class BugOra37447394_async(tests.MySQLConnectorAioTestCase):
8933-
"""BUG#37447394: Unable to escape a parameter marker (`%s`) used in a query that should not be
8934-
treated as a parameter marker.
8935-
8936-
For more details check `test_bugs.BugOra37447394`.
8937-
"""
8938-
8939-
stmt = 'select date_format(%s, "%Y-%m-%d %H:%i:%%s")'
8940-
params = ("2017-06-15 12:20:23", )
8941-
8942-
@foreach_cnx_aio()
8943-
async def test_bug37447394_async(self):
8944-
try:
8945-
async with await self.cnx.cursor() as cur:
8946-
await cur.execute(self.stmt, self.params)
8947-
self.assertEqual(await cur.fetchone(), self.params)
8948-
async with await self.cnx.cursor(prepared=True) as cur:
8949-
await cur.execute(self.stmt, self.params)
8950-
self.assertEqual(await cur.fetchone(), self.params)
8951-
except Exception as err:
8952-
self.fail(err)
8953-
89548903
class BugOra37275524(tests.MySQLConnectorTests):
89558904
"""BUG#37275524: Exception is not interpreted properly on prepared statements when C extension is in use
89568905

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy