diff options
author | Erlend Egeberg Aasland <erlend.aasland@protonmail.com> | 2022-05-16 15:39:17 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-16 15:39:17 (GMT) |
commit | 69cf0203ab47692efbc261c028e15e0d7a245c57 (patch) | |
tree | 77bee6f7687052409e13b72d19429c5a639eb02c /Modules/_sqlite | |
parent | 7ccdec3d1d837b910cd4fc5525ecde71a1326202 (diff) | |
download | cpython-69cf0203ab47692efbc261c028e15e0d7a245c57.zip cpython-69cf0203ab47692efbc261c028e15e0d7a245c57.tar.gz cpython-69cf0203ab47692efbc261c028e15e0d7a245c57.tar.bz2 |
[3.8] gh-80254: Disallow recursive usage of cursors in sqlite3 converters (#92333)
(cherry picked from commit c908dc5b4798c311981bd7e1f7d92fb623ee448b)
Co-authored-by: Sergey Fedoseev <fedoseev.sergey@gmail.com>
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Diffstat (limited to 'Modules/_sqlite')
-rw-r--r-- | Modules/_sqlite/cursor.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 8cfa6e5..996a83e 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -27,10 +27,25 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self); +static inline int +check_cursor_locked(pysqlite_Cursor *cur) +{ + if (cur->locked) { + PyErr_SetString(pysqlite_ProgrammingError, + "Recursive use of cursors not allowed."); + return 0; + } + return 1; +} + static const char errmsg_fetch_across_rollback[] = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from."; static int pysqlite_cursor_init(pysqlite_Cursor* self, PyObject* args, PyObject* kwargs) { + if (!check_cursor_locked(self)) { + return -1; + } + pysqlite_Connection* connection; if (!PyArg_ParseTuple(args, "O!", &pysqlite_ConnectionType, &connection)) @@ -357,12 +372,9 @@ static int check_cursor(pysqlite_Cursor* cur) return 0; } - if (cur->locked) { - PyErr_SetString(pysqlite_ProgrammingError, "Recursive use of cursors not allowed."); - return 0; - } - - return pysqlite_check_thread(cur->connection) && pysqlite_check_connection(cur->connection); + return (pysqlite_check_thread(cur->connection) + && pysqlite_check_connection(cur->connection) + && check_cursor_locked(cur)); } static PyObject * @@ -761,27 +773,29 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) if (self->statement) { rc = pysqlite_step(self->statement->st, self->connection); if (PyErr_Occurred()) { - (void)pysqlite_statement_reset(self->statement); - Py_DECREF(next_row); - return NULL; + goto error; } if (rc != SQLITE_DONE && rc != SQLITE_ROW) { - (void)pysqlite_statement_reset(self->statement); - Py_DECREF(next_row); _pysqlite_seterror(self->connection->db, NULL); - return NULL; + goto error; } if (rc == SQLITE_ROW) { + self->locked = 1; // GH-80254: Prevent recursive use of cursors. self->next_row = _pysqlite_fetch_one_row(self); + self->locked = 0; if (self->next_row == NULL) { - (void)pysqlite_statement_reset(self->statement); - return NULL; + goto error; } } } return next_row; + +error: + (void)pysqlite_statement_reset(self->statement); + Py_DECREF(next_row); + return NULL; } PyObject* pysqlite_cursor_fetchone(pysqlite_Cursor* self, PyObject* args) @@ -876,6 +890,10 @@ PyObject* pysqlite_noop(pysqlite_Connection* self, PyObject* args) PyObject* pysqlite_cursor_close(pysqlite_Cursor* self, PyObject* args) { + if (!check_cursor_locked(self)) { + return NULL; + } + if (!self->connection) { PyErr_SetString(pysqlite_ProgrammingError, "Base Cursor.__init__ not called."); |