Skip to content

Commit

Permalink
gh-89289: Harden sqlite3.Connection init (#92214)
Browse files Browse the repository at this point in the history
- Make sure SQLite resources are freed if database open fails
- Remove unneeded branches if init is aborted
  • Loading branch information
erlend-aasland committed May 3, 2022
1 parent 2eca5da commit c278474
Showing 1 changed file with 15 additions and 8 deletions.
23 changes: 15 additions & 8 deletions Modules/_sqlite/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,27 +226,27 @@ pysqlite_connection_init_impl(pysqlite_Connection *self,
pysqlite_state *state = pysqlite_get_state_by_type(Py_TYPE(self));
if (rc != SQLITE_OK) {
_pysqlite_seterror(state, db);
return -1;
goto error;
}

// Create LRU statement cache; returns a new reference.
PyObject *statement_cache = new_statement_cache(self, state, cache_size);
if (statement_cache == NULL) {
return -1;
goto error;
}

/* Create lists of weak references to cursors and blobs */
PyObject *cursors = PyList_New(0);
if (cursors == NULL) {
Py_XDECREF(statement_cache);
return -1;
Py_DECREF(statement_cache);
goto error;
}

PyObject *blobs = PyList_New(0);
if (blobs == NULL) {
Py_XDECREF(statement_cache);
Py_XDECREF(cursors);
return -1;
Py_DECREF(statement_cache);
Py_DECREF(cursors);
goto error;
}

// Init connection state members.
Expand Down Expand Up @@ -279,11 +279,18 @@ pysqlite_connection_init_impl(pysqlite_Connection *self,
self->NotSupportedError = state->NotSupportedError;

if (PySys_Audit("sqlite3.connect/handle", "O", self) < 0) {
return -1;
return -1; // Don't goto error; at this point, dealloc will clean up.
}

self->initialized = 1;
return 0;

error:
// There are no statements or other SQLite objects attached to the
// database, so sqlite3_close() should always return SQLITE_OK.
rc = sqlite3_close(db);
assert(rc == SQLITE_OK), rc;
return -1;
}

#define VISIT_CALLBACK_CONTEXT(ctx) \
Expand Down

0 comments on commit c278474

Please sign in to comment.