diff options
author | Erlend Egeberg Aasland <erlend.aasland@innova.no> | 2021-07-29 19:45:32 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-07-29 19:45:32 (GMT) |
commit | 7e311e496b0e26b3d3c62fe9b0ed2a4677c37ee9 (patch) | |
tree | 46ec9f66a8da29a76531818fca182b11b889eb95 /Modules | |
parent | 8182c8329c709f42218a8a17d81639ece5b7b627 (diff) | |
download | cpython-7e311e496b0e26b3d3c62fe9b0ed2a4677c37ee9.zip cpython-7e311e496b0e26b3d3c62fe9b0ed2a4677c37ee9.tar.gz cpython-7e311e496b0e26b3d3c62fe9b0ed2a4677c37ee9.tar.bz2 |
bpo-31746: Prevent segfaults when sqlite3.Connection is uninitialised (GH-27431)
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_sqlite/connection.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c index a95b75a..dd332e5 100644 --- a/Modules/_sqlite/connection.c +++ b/Modules/_sqlite/connection.c @@ -111,8 +111,6 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, const char *database = PyBytes_AsString(database_obj); - self->initialized = 1; - self->begin_statement = NULL; Py_CLEAR(self->statement_cache); @@ -147,7 +145,7 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, Py_INCREF(isolation_level); } Py_CLEAR(self->isolation_level); - if (pysqlite_connection_set_isolation_level(self, isolation_level, NULL) < 0) { + if (pysqlite_connection_set_isolation_level(self, isolation_level, NULL) != 0) { Py_DECREF(isolation_level); return -1; } @@ -195,6 +193,8 @@ pysqlite_connection_init_impl(pysqlite_Connection *self, return -1; } + self->initialized = 1; + return 0; } @@ -371,6 +371,13 @@ pysqlite_connection_close_impl(pysqlite_Connection *self) return NULL; } + if (!self->initialized) { + pysqlite_state *state = pysqlite_get_state(NULL); + PyErr_SetString(state->ProgrammingError, + "Base Connection.__init__ not called."); + return NULL; + } + pysqlite_do_all_statements(self, ACTION_FINALIZE, 1); connection_close(self); @@ -1258,6 +1265,9 @@ int pysqlite_check_thread(pysqlite_Connection* self) static PyObject* pysqlite_connection_get_isolation_level(pysqlite_Connection* self, void* unused) { + if (!pysqlite_check_connection(self)) { + return NULL; + } return Py_NewRef(self->isolation_level); } @@ -1289,11 +1299,17 @@ pysqlite_connection_set_isolation_level(pysqlite_Connection* self, PyObject* iso return -1; } if (isolation_level == Py_None) { - PyObject *res = pysqlite_connection_commit(self, NULL); - if (!res) { - return -1; + /* We might get called during connection init, so we cannot use + * pysqlite_connection_commit() here. */ + if (self->db && !sqlite3_get_autocommit(self->db)) { + int rc; + Py_BEGIN_ALLOW_THREADS + rc = sqlite3_exec(self->db, "COMMIT", NULL, NULL, NULL); + Py_END_ALLOW_THREADS + if (rc != SQLITE_OK) { + return _pysqlite_seterror(self->db); + } } - Py_DECREF(res); self->begin_statement = NULL; } else { |