Commit 297d1042 authored by Victor Stinner's avatar Victor Stinner

Issue #21858: Better handling of Python exceptions in the sqlite3 module.

parent 7180c793
...@@ -27,6 +27,8 @@ Core and Builtins ...@@ -27,6 +27,8 @@ Core and Builtins
Library Library
------- -------
- Issue #21858: Better handling of Python exceptions in the sqlite3 module.
- Issue #21476: Make sure the email.parser.BytesParser TextIOWrapper is - Issue #21476: Make sure the email.parser.BytesParser TextIOWrapper is
discarded after parsing, so the input file isn't unexpectedly closed. discarded after parsing, so the input file isn't unexpectedly closed.
......
...@@ -289,9 +289,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) ...@@ -289,9 +289,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
row = PyTuple_New(numcols); row = PyTuple_New(numcols);
if (!row) { if (!row)
return NULL; return NULL;
}
for (i = 0; i < numcols; i++) { for (i = 0; i < numcols; i++) {
if (self->connection->detect_types) { if (self->connection->detect_types) {
...@@ -311,14 +310,12 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) ...@@ -311,14 +310,12 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
converted = Py_None; converted = Py_None;
} else { } else {
item = PyBytes_FromStringAndSize(val_str, nbytes); item = PyBytes_FromStringAndSize(val_str, nbytes);
if (!item) { if (!item)
return NULL; goto error;
}
converted = PyObject_CallFunction(converter, "O", item); converted = PyObject_CallFunction(converter, "O", item);
Py_DECREF(item); Py_DECREF(item);
if (!converted) { if (!converted)
break; break;
}
} }
} else { } else {
Py_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
...@@ -374,9 +371,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) ...@@ -374,9 +371,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
nbytes = sqlite3_column_bytes(self->statement->st, i); nbytes = sqlite3_column_bytes(self->statement->st, i);
buffer = PyBytes_FromStringAndSize( buffer = PyBytes_FromStringAndSize(
sqlite3_column_blob(self->statement->st, i), nbytes); sqlite3_column_blob(self->statement->st, i), nbytes);
if (!buffer) { if (!buffer)
break; break;
}
converted = buffer; converted = buffer;
} }
} }
...@@ -389,12 +385,14 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self) ...@@ -389,12 +385,14 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
} }
} }
if (PyErr_Occurred()) { if (PyErr_Occurred())
Py_DECREF(row); goto error;
row = NULL;
}
return row; return row;
error:
Py_DECREF(row);
return NULL;
} }
/* /*
...@@ -612,6 +610,10 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* ...@@ -612,6 +610,10 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
while (1) { while (1) {
/* Actually execute the SQL statement. */ /* Actually execute the SQL statement. */
rc = pysqlite_step(self->statement->st, self->connection); 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 (rc == SQLITE_DONE || rc == SQLITE_ROW) {
/* If it worked, let's get out of the loop */ /* If it worked, let's get out of the loop */
break; break;
...@@ -685,6 +687,8 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject* ...@@ -685,6 +687,8 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
} }
self->next_row = _pysqlite_fetch_one_row(self); self->next_row = _pysqlite_fetch_one_row(self);
if (self->next_row == NULL)
goto error;
} else if (rc == SQLITE_DONE && !multiple) { } else if (rc == SQLITE_DONE && !multiple) {
pysqlite_statement_reset(self->statement); pysqlite_statement_reset(self->statement);
Py_CLEAR(self->statement); Py_CLEAR(self->statement);
...@@ -807,7 +811,10 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args) ...@@ -807,7 +811,10 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
rc = SQLITE_ROW; rc = SQLITE_ROW;
while (rc == SQLITE_ROW) { while (rc == SQLITE_ROW) {
rc = pysqlite_step(statement, self->connection); 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) { if (rc != SQLITE_DONE) {
...@@ -884,6 +891,11 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) ...@@ -884,6 +891,11 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self)
if (self->statement) { if (self->statement) {
rc = pysqlite_step(self->statement->st, self->connection); 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) { if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
(void)pysqlite_statement_reset(self->statement); (void)pysqlite_statement_reset(self->statement);
Py_DECREF(next_row); Py_DECREF(next_row);
...@@ -895,8 +907,6 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self) ...@@ -895,8 +907,6 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self)
self->next_row = _pysqlite_fetch_one_row(self); self->next_row = _pysqlite_fetch_one_row(self);
if (self->next_row == NULL) { if (self->next_row == NULL) {
(void)pysqlite_statement_reset(self->statement); (void)pysqlite_statement_reset(self->statement);
Py_DECREF(next_row);
_pysqlite_seterror(self->connection->db, NULL);
return NULL; return NULL;
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment