http://hg.python.org/cpython/rev/62612b195cb5 changeset: 91432:62612b195cb5 branch: 3.4 parent: 91429:ab708e4131dd user: Victor Stinner <victor.stinner@gmail.com> date: Thu Jun 26 23:32:00 2014 +0200 summary: Issue #21858: Better handling of Python exceptions in the sqlite3 module. files: Misc/NEWS | 2 + Modules/_sqlite/cursor.c | 42 +++++++++++++++++---------- 2 files changed, 28 insertions(+), 16 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -27,6 +27,8 @@ Library ------- +- Issue #21858: Better handling of Python exceptions in the sqlite3 module. + - Issue #21476: Make sure the email.parser.BytesParser TextIOWrapper is discarded after parsing, so the input file isn't unexpectedly closed. diff --git a/Modules/_sqlite/cursor.c b/Modules/_sqlite/cursor.c --- a/Modules/_sqlite/cursor.c +++ b/Modules/_sqlite/cursor.c @@ -289,9 +289,8 @@ 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) { @@ -311,14 +310,12 @@ 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 @@ -374,9 +371,8 @@ 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; } } @@ -389,12 +385,14 @@ } } - if (PyErr_Occurred()) { - Py_DECREF(row); - row = NULL; - } + if (PyErr_Occurred()) + goto error; return row; + +error: + Py_DECREF(row); + return NULL; } /* @@ -612,6 +610,10 @@ 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; @@ -685,6 +687,8 @@ } 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); @@ -807,7 +811,10 @@ 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) { @@ -884,6 +891,11 @@ 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); @@ -895,8 +907,6 @@ self->next_row = _pysqlite_fetch_one_row(self); if (self->next_row == NULL) { (void)pysqlite_statement_reset(self->statement); - Py_DECREF(next_row); - _pysqlite_seterror(self->connection->db, NULL); return NULL; } } -- Repository URL: http://hg.python.org/cpython