diff options
author | Erlend Egeberg Aasland <erlend.aasland@protonmail.com> | 2022-05-03 18:18:11 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-03 18:18:11 (GMT) |
commit | c278474df97de310535425c207136bf26c663e0b (patch) | |
tree | f86f382dac8be2ff7b96ecf232a9cdb51d613c46 | |
parent | 2eca5dad0a783153318e91e3e25f16a38a632bfd (diff) | |
download | cpython-c278474df97de310535425c207136bf26c663e0b.zip cpython-c278474df97de310535425c207136bf26c663e0b.tar.gz cpython-c278474df97de310535425c207136bf26c663e0b.tar.bz2 |
gh-89289: Harden sqlite3.Connection init (#92214)
- Make sure SQLite resources are freed if database open fails
- Remove unneeded branches if init is aborted
-rw-r--r-- | Modules/_sqlite/connection.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index 75d2970..793bc0b 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -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. @@ -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) \ |