Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 16 additions & 1 deletion Lib/test/test_sqlite3/test_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,10 +389,25 @@ def test_autocommit_setget(self):

def test_autocommit_setget_invalid(self):
msg = "autocommit must be True, False, or.*LEGACY"
for mode in "a", 12, (), None:
for mode in "a", 12, (), None, 2**1000, -2**1000:
with self.subTest(mode=mode):
with self.assertRaisesRegex(ValueError, msg):
sqlite.connect(":memory:", autocommit=mode)
with memory_database() as cx:
with self.assertRaisesRegex(ValueError, msg):
cx.autocommit = mode
# a failed assignment does not change the value
self.assertEqual(cx.autocommit,
sqlite.LEGACY_TRANSACTION_CONTROL)

def test_autocommit_delete(self):
with memory_database() as cx:
cx.autocommit = False
with self.assertRaisesRegex(AttributeError,
"cannot delete autocommit attribute"):
del cx.autocommit
# a failed deletion does not change the value
self.assertIs(cx.autocommit, False)

def test_autocommit_disabled(self):
expected = [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fix crashes in :class:`sqlite3.Connection` when deleting the
:attr:`~sqlite3.Connection.autocommit` attribute or setting it to an integer
which does not fit in C :c:expr:`long`.
Both now raise an exception.
20 changes: 15 additions & 5 deletions Modules/_sqlite/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,16 @@ autocommit_converter(PyObject *val, enum autocommit_mode *result)
*result = AUTOCOMMIT_DISABLED;
return 1;
}
if (PyLong_Check(val) &&
PyLong_AsLong(val) == LEGACY_TRANSACTION_CONTROL)
{
*result = AUTOCOMMIT_LEGACY;
return 1;
if (PyLong_Check(val)) {
int overflow;
long value = PyLong_AsLongAndOverflow(val, &overflow);
if (value == -1 && PyErr_Occurred()) {
return 0;
}
if (!overflow && value == LEGACY_TRANSACTION_CONTROL) {
*result = AUTOCOMMIT_LEGACY;
return 1;
}
}

PyErr_SetString(PyExc_ValueError,
Expand Down Expand Up @@ -2621,6 +2626,11 @@ static int
set_autocommit(PyObject *op, PyObject *val, void *Py_UNUSED(closure))
{
pysqlite_Connection *self = _pysqlite_Connection_CAST(op);
if (val == NULL) {
PyErr_SetString(PyExc_AttributeError,
"cannot delete autocommit attribute");
return -1;
}
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
return -1;
}
Expand Down
Loading