Skip to content

Commit 24dcf48

Browse files
isrgomeznmariz
authored andcommitted
BUG32120659: Prepared statements w/o parameters violates MySQL protocol
Connector python violates MySQL protocol sending unrequired extra bytes with a prepared statement without any parameter. like for: cur.execute("SELECT 1") Before: b'\x0b\x00\x00\x00\x17\x01\x00\x00\x00\x00\x01\x00\x00\x00\x01' Now: b'\x0a\x00\x00\x00\x17\x01\x00\x00\x00\x00\x01\x00\x00\x00'
1 parent 68ba719 commit 24dcf48

File tree

4 files changed

+16
-11
lines changed

4 files changed

+16
-11
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ v8.0.24
1717
- WL#14027: Add support for Python 3.9
1818
- BUG#32435181: Add support for Django 3.2
1919
- BUG#32162928: Change user command fails on pure python implementation
20+
- BUG#32120659: Prepared statements w/o parameters violates MySQL protocol
2021
- BUG#32039427: Remove python 3.4 support in MSI packaging
2122
- BUG#32029891: Add context manager support for pooled connections
2223
- BUG#31490101: Fix wrong cast of Python unicode to std::string

lib/mysql/connector/protocol.py

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -727,17 +727,17 @@ def make_stmt_execute(self, statement_id, data=(), parameters=(),
727727
packet = (
728728
utils.int4store(statement_id) +
729729
utils.int1store(0) +
730-
utils.int4store(iteration_count) +
731-
b''.join([struct.pack('B', bit) for bit in null_bitmap]) +
732-
utils.int1store(1)
733-
)
734-
735-
for a_type in types:
736-
packet += a_type
730+
utils.int4store(iteration_count))
731+
if len(parameters) > 0:
732+
packet += (
733+
b''.join([struct.pack('B', bit) for bit in null_bitmap]) +
734+
utils.int1store(1))
737735

738-
for a_value in values:
739-
packet += a_value
736+
for a_type in types:
737+
packet += a_type
740738

739+
for a_value in values:
740+
packet += a_value
741741
return packet
742742

743743
def parse_auth_switch_request(self, packet):

src/mysql_capi.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2852,7 +2852,7 @@ MySQL_stmt_prepare(MySQL *self, PyObject *args)
28522852
MYSQL_RES *mysql_res= NULL;
28532853
int res= 0;
28542854
const char *stmt_char= NULL;
2855-
unsigned int stmt_length= 0;
2855+
unsigned long stmt_length= 0;
28562856
unsigned long param_count= 0;
28572857
PyObject *stmt;
28582858
PyObject *prep_stmt;
@@ -2865,7 +2865,6 @@ MySQL_stmt_prepare(MySQL *self, PyObject *args)
28652865
}
28662866
stmt_char= PyBytes_AsString(stmt);
28672867
stmt_length= strlen(stmt_char);
2868-
28692868
mysql= &self->session;
28702869

28712870
Py_BEGIN_ALLOW_THREADS

tests/test_protocol.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,11 @@ def test_make_stmt_execute(self):
503503
self._protocol.make_stmt_execute, statement_id,
504504
('ham', 'spam'), (1, 2, 3))
505505

506+
# Testing with no parameters
507+
exp = bytearray(b'\x01\x00\x00\x00\x00\x01\x00\x00\x00')
508+
res = self._protocol.make_stmt_execute(statement_id)
509+
self.assertEqual(exp, res)
510+
506511
data = ('ham', 'spam')
507512
exp = bytearray(
508513
b'\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x01\x0f'

0 commit comments

Comments
 (0)