Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 35.2k
bpo-31746: Fixed Segfaults in the sqlite module when uninitialized.#3946
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
bbe3a0eb57a6af9955edfc0920c877b29460fcd075d8b4dd651e7a9f84326a2File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -414,6 +414,33 @@ def test_return_empty_bytestring(self): | ||
| val = cur.fetchone()[0] | ||
| self.assertEqual(val, b'') | ||
| def test_uninitialized_isolation_level(self): | ||
| """ | ||
| Previously trying to get the isolation level of an uninitialized Connection | ||
| caused a segfault, now it should just return None. | ||
| """ | ||
| conn = sqlite.Connection.__new__(sqlite.Connection) | ||
| with self.assertRaises(sqlite.ProgrammingError): | ||
| conn.isolation_level | ||
| def test_cursor_invalid_isolation_level(self): | ||
| """ | ||
| When trying to call conn.cursor() when conn is a Connection object that | ||
| was not initialized properly, it caused a segfault. Now it should raise | ||
| a ProgrammingError. | ||
| """ | ||
| conn = sqlite.Connection.__new__(sqlite.Connection) | ||
| self.assertRaises(ValueError, conn.__init__, '', isolation_level='invalid isolation level') | ||
| self.assertRaises(sqlite.ProgrammingError, conn.cursor) | ||
| def test_close_invalid_connection(self): | ||
| """ | ||
| Trying to call close() on a connection which was not initialized properly, | ||
| it caused a segfault. Now it should raise a ProgrammingError. | ||
| """ | ||
| conn = sqlite.Connection.__new__(sqlite.Connection) | ||
| self.assertRaises(sqlite.ProgrammingError, conn.close) | ||
lielfr marked this conversation as resolved.
Outdated
Uh oh!There was an error while loading. Please reload this page. | ||
| def suite(): | ||
| tests = [ | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -118,11 +118,15 @@ pysqlite_connection_init(pysqlite_Connection *self, PyObject *args, | ||||||||||||||||||
| if (!isolation_level) { | ||||||||||||||||||
| isolation_level = PyUnicode_FromString(""); | ||||||||||||||||||
| if (!isolation_level) { | ||||||||||||||||||
| PyErr_SetString(pysqlite_ProgrammingError, "Isolation level could not be set."); | ||||||||||||||||||
| return -1; | ||||||||||||||||||
| } | ||||||||||||||||||
| } else { | ||||||||||||||||||
| Py_INCREF(isolation_level); | ||||||||||||||||||
| } | ||||||||||||||||||
| self->initialized = 1; | ||||||||||||||||||
lielfr marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||||||||||||||||||
| Py_CLEAR(self->isolation_level); | ||||||||||||||||||
| if (pysqlite_connection_set_isolation_level(self, isolation_level, NULL) < 0) { | ||||||||||||||||||
| Py_DECREF(isolation_level); | ||||||||||||||||||
| @@ -250,8 +254,19 @@ pysqlite_connection_dealloc(pysqlite_Connection *self) | ||||||||||||||||||
| */ | ||||||||||||||||||
| int pysqlite_connection_register_cursor(pysqlite_Connection* connection, PyObject* cursor) | ||||||||||||||||||
| { | ||||||||||||||||||
| if (!connection || !connection->cursors) { | ||||||||||||||||||
| PyErr_Format(pysqlite_ProgrammingError, | ||||||||||||||||||
lielfr marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||||||||||||||||||
| "Base Connection.__init__ not called."); | ||||||||||||||||||
| goto error; | ||||||||||||||||||
| } | ||||||||||||||||||
| PyObject* weakref; | ||||||||||||||||||
| if (!connection->cursors) { | ||||||||||||||||||
| PyErr_SetString(pysqlite_ProgrammingError, | ||||||||||||||||||
| "Base Connection.__init__ not called."); | ||||||||||||||||||
| goto error; | ||||||||||||||||||
| } | ||||||||||||||||||
| weakref = PyWeakref_NewRef((PyObject*)cursor, NULL); | ||||||||||||||||||
| if (!weakref) { | ||||||||||||||||||
| goto error; | ||||||||||||||||||
| @@ -281,6 +296,11 @@ static PyObject * | ||||||||||||||||||
| pysqlite_connection_cursor_impl(pysqlite_Connection *self, PyObject *factory) | ||||||||||||||||||
| /*[clinic end generated code: output=562432a9e6af2aa1 input=4127345aa091b650]*/ | ||||||||||||||||||
| { | ||||||||||||||||||
| if (self == NULL) { | ||||||||||||||||||
| return NULL; | ||||||||||||||||||
| } | ||||||||||||||||||
| static char *kwlist[] = {"factory", NULL}; | ||||||||||||||||||
Comment on lines
+299
to
+303
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not needed if | ||||||||||||||||||
| PyObject* cursor; | ||||||||||||||||||
| if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) { | ||||||||||||||||||
| @@ -323,6 +343,12 @@ pysqlite_connection_close_impl(pysqlite_Connection *self) | ||||||||||||||||||
| /*[clinic end generated code: output=a546a0da212c9b97 input=3d58064bbffaa3d3]*/ | ||||||||||||||||||
| { | ||||||||||||||||||
| int rc; | ||||||||||||||||||
| if (!self->statements) { | ||||||||||||||||||
| PyErr_SetString(pysqlite_ProgrammingError, | ||||||||||||||||||
| "Base Connection.__init__ not called."); | ||||||||||||||||||
| return NULL; | ||||||||||||||||||
| } | ||||||||||||||||||
Comment on lines
+346
to
+351
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't it be better to handle this in Author There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Are you sure about splitting Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No, I'm not sure :) Let's leave it as it is; both Nit: | ||||||||||||||||||
| if (!pysqlite_check_thread(self)) { | ||||||||||||||||||
| return NULL; | ||||||||||||||||||
| @@ -1225,6 +1251,11 @@ int pysqlite_check_thread(pysqlite_Connection* self) | ||||||||||||||||||
| static PyObject* pysqlite_connection_get_isolation_level(pysqlite_Connection* self, void* unused) | ||||||||||||||||||
| { | ||||||||||||||||||
| if (!self || !self->isolation_level) { | ||||||||||||||||||
| PyErr_Format(pysqlite_ProgrammingError, | ||||||||||||||||||
| "Object is null or isolation_level is uninitialized."); | ||||||||||||||||||
| return 0; | ||||||||||||||||||
| } | ||||||||||||||||||
Comment on lines
+1254
to
+1258
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If
Suggested change
| ||||||||||||||||||
| return Py_NewRef(self->isolation_level); | ||||||||||||||||||
| } | ||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Other getters raise a
ProgrammingErrorwhen they are called on an uninitializedConnectionobject.IMHO this should be the same here.