https://github.com/python/cpython/commit/daebcac92d422d7fe9611cbe89044af23ea857c3
commit: daebcac92d422d7fe9611cbe89044af23ea857c3
branch: main
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-08-21T10:04:25+03:00
summary:
gh-156100: Fix crashes in the sqlite3 Connection.autocommit setter (GH-156104)
Deleting the attribute crashed, and setting it to an integer which does not
fit in C long reported success with OverflowError set.
files:
A Misc/NEWS.d/next/Library/2026-08-20-12-05-00.gh-issue-156100.Lm7qWz.rst
M Lib/test/test_sqlite3/test_transactions.py
M Modules/_sqlite/connection.c
diff --git a/Lib/test/test_sqlite3/test_transactions.py
b/Lib/test/test_sqlite3/test_transactions.py
index a3de7a7a82ec1cb..2e5d60fe9ba5fc0 100644
--- a/Lib/test/test_sqlite3/test_transactions.py
+++ b/Lib/test/test_sqlite3/test_transactions.py
@@ -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 = [
diff --git
a/Misc/NEWS.d/next/Library/2026-08-20-12-05-00.gh-issue-156100.Lm7qWz.rst
b/Misc/NEWS.d/next/Library/2026-08-20-12-05-00.gh-issue-156100.Lm7qWz.rst
new file mode 100644
index 000000000000000..8c296a9a8919fc3
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-08-20-12-05-00.gh-issue-156100.Lm7qWz.rst
@@ -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.
diff --git a/Modules/_sqlite/connection.c b/Modules/_sqlite/connection.c
index 892740b05e55c98..ec47471873f7822 100644
--- a/Modules/_sqlite/connection.c
+++ b/Modules/_sqlite/connection.c
@@ -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,
@@ -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;
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]