Skip to content

Commit 70e8839

Browse files
committed
BUG32165864: Fix segmentation fault when using invalid SQL with prepared statements
This patch fixes the segmentation fault when using invalid SQL syntax with prepared statements. A test was added for regression.
1 parent 9ff99a3 commit 70e8839

File tree

4 files changed

+35
-3
lines changed

4 files changed

+35
-3
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ v8.0.23
1414
- WL#14238: Deprecate Python 2.7 support
1515
- WL#14215: Replace language in APIs and source code/docs
1616
- WL#14213: Support GSSAPI - Kerberos auth
17+
- BUG#32165864: Fix segmentation fault when using invalid SQL with prepared statements
1718
- BUG#31882419: Fix error when getting the connection ID from a CMySQLConnection
1819
- BUG#29195610: Fix cursor.callproc() using namedtuple and dictionary cursors
1920
- BUG#26834307: Make cursor.fetchone() and cursor.fetchmany() PEP 249 compliant

lib/mysql/connector/cursor_cext.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -959,7 +959,8 @@ def execute(self, operation, params=(), multi=False): # multi is unused
959959

960960
try:
961961
self._stmt = self._cnx.cmd_stmt_prepare(operation)
962-
except (errors.Error, errors.ProgrammingError):
962+
except errors.Error:
963+
self._executed = None
963964
self._stmt = None
964965
raise
965966

src/mysql_capi.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2987,7 +2987,7 @@ MySQL_stmt_prepare(MySQL *self, PyObject *args)
29872987

29882988
IS_CONNECTED(self);
29892989

2990-
if (!PyArg_ParseTuple(args, "O", &stmt))
2990+
if (!PyArg_ParseTuple(args, "S", &stmt))
29912991
{
29922992
return NULL;
29932993
}
@@ -3033,7 +3033,6 @@ MySQL_stmt_prepare(MySQL *self, PyObject *args)
30333033
return prep_stmt;
30343034

30353035
error:
3036-
Py_XDECREF(stmt);
30373036
Py_BEGIN_ALLOW_THREADS
30383037
mysql_stmt_close(mysql_stmt);
30393038
Py_END_ALLOW_THREADS

tests/test_bugs.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5808,3 +5808,34 @@ def test_datetime_fractional(self):
58085808
self.assertEqual(row[0], datetime(2020, 1, 1, 1, 1, 1, 543000))
58095809
self.assertEqual(row[1], "2020-01-01 01:01:01.543")
58105810
cur.execute("DROP TABLE IF EXISTS bug24938411")
5811+
5812+
5813+
class BugOra32165864(tests.MySQLConnectorTests):
5814+
"""BUG#32165864: SEGMENTATION FAULT WHEN TWO PREPARED STATEMENTS WITH
5815+
INCORRECT SQL SYNTAX ARE EXECUTED CONSECUTIVELY.
5816+
"""
5817+
5818+
@foreach_cnx()
5819+
def test_segfault_prepared_statement(self):
5820+
with self.cnx.cursor() as cur:
5821+
cur.execute("DROP TABLE IF EXISTS bug32165864")
5822+
cur.execute(
5823+
"CREATE TABLE bug32165864 "
5824+
"(id INT, name VARCHAR(10), address VARCHAR(20))"
5825+
)
5826+
cur.execute(
5827+
"INSERT INTO bug32165864 (id, name, address) VALUES "
5828+
"(1, 'Joe', 'Street 1'), (2, 'John', 'Street 2')"
5829+
)
5830+
self.cnx.commit()
5831+
5832+
stmt = "SELECT * FROM customer WHERE i = ? ?"
5833+
5834+
with self.cnx.cursor(prepared=True) as cur:
5835+
for _ in range(10):
5836+
self.assertRaises(
5837+
errors.Error, cur.execute, stmt, (10, "Gabriela")
5838+
)
5839+
5840+
with self.cnx.cursor() as cur:
5841+
cur.execute("DROP TABLE IF EXISTS bug32165864")

0 commit comments

Comments
 (0)