diff options
Diffstat (limited to 'Modules/_sqlite/cursor.c')
-rw-r--r-- | Modules/_sqlite/cursor.c | 55 |
1 files changed, 40 insertions, 15 deletions
diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c index 09c13d4..db96b02 100644 --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -24,7 +24,6 @@ #include "cursor.h" #include "module.h" #include "util.h" -#include "sqlitecompat.h" PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self); @@ -290,9 +289,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) Py_END_ALLOW_THREADS row = PyTuple_New(numcols); - if (!row) { + if (!row) return NULL; - } for (i = 0; i < numcols; i++) { if (self->connection->detect_types) { @@ -312,14 +310,12 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) converted = Py_None; } else { item = PyBytes_FromStringAndSize(val_str, nbytes); - if (!item) { - return NULL; - } + if (!item) + goto error; converted = PyObject_CallFunction(converter, "O", item); Py_DECREF(item); - if (!converted) { + if (!converted) break; - } } } else { Py_BEGIN_ALLOW_THREADS @@ -338,6 +334,11 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) if (self->connection->text_factory == (PyObject*)&PyUnicode_Type) { converted = PyUnicode_FromStringAndSize(val_str, nbytes); if (!converted) { +#ifdef Py_DEBUG + /* in debug mode, type_call() fails with an assertion + error if an exception is set when it is called */ + PyErr_Clear(); +#endif colname = sqlite3_column_name(self->statement->st, i); if (!colname) { colname = "<unknown column name>"; @@ -370,9 +371,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) nbytes = sqlite3_column_bytes(self->statement->st, i); buffer = PyBytes_FromStringAndSize( sqlite3_column_blob(self->statement->st, i), nbytes); - if (!buffer) { + if (!buffer) break; - } converted = buffer; } } @@ -385,12 +385,14 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) } } - if (PyErr_Occurred()) { - Py_DECREF(row); - row = NULL; - } + if (PyErr_Occurred()) + goto error; return row; + +error: + Py_DECREF(row); + return NULL; } /* @@ -608,6 +610,10 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* while (1) { /* Actually execute the SQL statement. */ rc = pysqlite_step(self->statement->st, self->connection); + if (PyErr_Occurred()) { + (void)pysqlite_statement_reset(self->statement); + goto error; + } if (rc == SQLITE_DONE || rc == SQLITE_ROW) { /* If it worked, let's get out of the loop */ break; @@ -681,6 +687,8 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* } self->next_row = _pysqlite_fetch_one_row(self); + if (self->next_row == NULL) + goto error; } else if (rc == SQLITE_DONE && !multiple) { pysqlite_statement_reset(self->statement); Py_CLEAR(self->statement); @@ -803,7 +811,10 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) rc = SQLITE_ROW; while (rc == SQLITE_ROW) { rc = pysqlite_step(statement, self->connection); - /* TODO: we probably need more error handling here */ + if (PyErr_Occurred()) { + (void)sqlite3_finalize(statement); + goto error; + } } if (rc != SQLITE_DONE) { @@ -864,10 +875,15 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) } next_row_tuple = self->next_row; + assert(next_row_tuple != NULL); self->next_row = NULL; if (self->row_factory != Py_None) { next_row = PyObject_CallFunction(self->row_factory, "OO", self, next_row_tuple); + if (next_row == NULL) { + self->next_row = next_row_tuple; + return NULL; + } Py_DECREF(next_row_tuple); } else { next_row = next_row_tuple; @@ -875,6 +891,11 @@ 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; + } if (rc != SQLITE_DONE && rc != SQLITE_ROW) { (void)pysqlite_statement_reset(self->statement); Py_DECREF(next_row); @@ -884,6 +905,10 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) if (rc == SQLITE_ROW) { self->next_row = _pysqlite_fetch_one_row(self); + if (self->next_row == NULL) { + (void)pysqlite_statement_reset(self->statement); + return NULL; + } } } |