Skip to content

Commit 297d104

Browse files
committed
Issue #21858: Better handling of Python exceptions in the sqlite3 module.
1 parent 7180c79 commit 297d104

2 files changed

Lines changed: 28 additions & 16 deletions

File tree

Misc/NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ Core and Builtins
2727
Library
2828
-------
2929

30+
- Issue #21858: Better handling of Python exceptions in the sqlite3 module.
31+
3032
- Issue #21476: Make sure the email.parser.BytesParser TextIOWrapper is
3133
discarded after parsing, so the input file isn't unexpectedly closed.
3234

Modules/_sqlite/cursor.c

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -289,9 +289,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
289289
Py_END_ALLOW_THREADS
290290

291291
row = PyTuple_New(numcols);
292-
if (!row) {
292+
if (!row)
293293
return NULL;
294-
}
295294

296295
for (i = 0; i < numcols; i++) {
297296
if (self->connection->detect_types) {
@@ -311,14 +310,12 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
311310
converted = Py_None;
312311
} else {
313312
item = PyBytes_FromStringAndSize(val_str, nbytes);
314-
if (!item) {
315-
return NULL;
316-
}
313+
if (!item)
314+
goto error;
317315
converted = PyObject_CallFunction(converter, "O", item);
318316
Py_DECREF(item);
319-
if (!converted) {
317+
if (!converted)
320318
break;
321-
}
322319
}
323320
} else {
324321
Py_BEGIN_ALLOW_THREADS
@@ -374,9 +371,8 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
374371
nbytes = sqlite3_column_bytes(self->statement->st, i);
375372
buffer = PyBytes_FromStringAndSize(
376373
sqlite3_column_blob(self->statement->st, i), nbytes);
377-
if (!buffer) {
374+
if (!buffer)
378375
break;
379-
}
380376
converted = buffer;
381377
}
382378
}
@@ -389,12 +385,14 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
389385
}
390386
}
391387

392-
if (PyErr_Occurred()) {
393-
Py_DECREF(row);
394-
row = NULL;
395-
}
388+
if (PyErr_Occurred())
389+
goto error;
396390

397391
return row;
392+
393+
error:
394+
Py_DECREF(row);
395+
return NULL;
398396
}
399397

400398
/*
@@ -612,6 +610,10 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
612610
while (1) {
613611
/* Actually execute the SQL statement. */
614612
rc = pysqlite_step(self->statement->st, self->connection);
613+
if (PyErr_Occurred()) {
614+
(void)pysqlite_statement_reset(self->statement);
615+
goto error;
616+
}
615617
if (rc == SQLITE_DONE || rc == SQLITE_ROW) {
616618
/* If it worked, let's get out of the loop */
617619
break;
@@ -685,6 +687,8 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
685687
}
686688

687689
self->next_row = _pysqlite_fetch_one_row(self);
690+
if (self->next_row == NULL)
691+
goto error;
688692
} else if (rc == SQLITE_DONE && !multiple) {
689693
pysqlite_statement_reset(self->statement);
690694
Py_CLEAR(self->statement);
@@ -807,7 +811,10 @@ PyObject* pysqlite_cursor_executescript(pysqlite_Cursor* self, PyObject* args)
807811
rc = SQLITE_ROW;
808812
while (rc == SQLITE_ROW) {
809813
rc = pysqlite_step(statement, self->connection);
810-
/* TODO: we probably need more error handling here */
814+
if (PyErr_Occurred()) {
815+
(void)sqlite3_finalize(statement);
816+
goto error;
817+
}
811818
}
812819

813820
if (rc != SQLITE_DONE) {
@@ -884,6 +891,11 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self)
884891

885892
if (self->statement) {
886893
rc = pysqlite_step(self->statement->st, self->connection);
894+
if (PyErr_Occurred()) {
895+
(void)pysqlite_statement_reset(self->statement);
896+
Py_DECREF(next_row);
897+
return NULL;
898+
}
887899
if (rc != SQLITE_DONE && rc != SQLITE_ROW) {
888900
(void)pysqlite_statement_reset(self->statement);
889901
Py_DECREF(next_row);
@@ -895,8 +907,6 @@ PyObject* pysqlite_cursor_iternext(pysqlite_Cursor *self)
895907
self->next_row = _pysqlite_fetch_one_row(self);
896908
if (self->next_row == NULL) {
897909
(void)pysqlite_statement_reset(self->statement);
898-
Py_DECREF(next_row);
899-
_pysqlite_seterror(self->connection->db, NULL);
900910
return NULL;
901911
}
902912
}

0 commit comments

Comments
 (0)