https://github.com/python/cpython/commit/503560dcadd9eaa42f152115b495143f1fc64ff2
commit: 503560dcadd9eaa42f152115b495143f1fc64ff2
branch: 3.15
author: Serhiy Storchaka <[email protected]>
committer: serhiy-storchaka <[email protected]>
date: 2026-10-09T18:35:20Z
summary:

[3.15] gh-150449: Raise ValueError for sqlite3.Blob slices with a negative step 
(GH-155773)

Reading or writing such a slice computed a negative length and failed with
SystemError.  Empty slices, which select nothing, are still allowed.

(cherry picked from commit d9e8d226a3d05ea020256086aee24d21f9792206)

files:
A Misc/NEWS.d/next/Library/2026-08-14-09-28-21.gh-issue-150449.Nf3Qz1.rst
M Lib/test/test_sqlite3/test_dbapi.py
M Modules/_sqlite/blob.c

diff --git a/Lib/test/test_sqlite3/test_dbapi.py 
b/Lib/test/test_sqlite3/test_dbapi.py
index 2cf3556f66d9639..80015de4eea14f4 100644
--- a/Lib/test/test_sqlite3/test_dbapi.py
+++ b/Lib/test/test_sqlite3/test_dbapi.py
@@ -1396,6 +1396,19 @@ def test_blob_set_slice(self):
         actual = self.cx.execute("select b from test").fetchone()[0]
         self.assertEqual(actual, expected)
 
+    def test_blob_slice_with_negative_step(self):
+        # gh-150449: this used to raise SystemError
+        for sl in (slice(9, 0, -2), slice(None, None, -1), slice(9, None, -2)):
+            with self.subTest(slice=sl):
+                with self.assertRaises(ValueError):
+                    self.blob[sl]
+                with self.assertRaises(ValueError):
+                    self.blob[sl] = b"1" * len(self.data[sl])
+        # an empty slice selects nothing and is still allowed
+        self.assertEqual(self.blob[3:8:-1], b"")
+        self.blob[3:8:-1] = b""
+        self.assertEqual(self.blob[:], self.data)
+
     def test_blob_set_slice_with_step_keeps_bytes_intact(self):
         # The buffer used for the read-patch-write cycle must not be the
         # bytes object read from the blob: for a single byte it is an
diff --git 
a/Misc/NEWS.d/next/Library/2026-08-14-09-28-21.gh-issue-150449.Nf3Qz1.rst 
b/Misc/NEWS.d/next/Library/2026-08-14-09-28-21.gh-issue-150449.Nf3Qz1.rst
new file mode 100644
index 000000000000000..5810596a5a507e5
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2026-08-14-09-28-21.gh-issue-150449.Nf3Qz1.rst
@@ -0,0 +1,3 @@
+Fix :class:`sqlite3.Blob` slices with a negative step.
+Reading or writing such a slice raised :exc:`SystemError`.
+It now raises :exc:`ValueError`.
diff --git a/Modules/_sqlite/blob.c b/Modules/_sqlite/blob.c
index 53d28a06181a9c1..5d9b9ad1ff88884 100644
--- a/Modules/_sqlite/blob.c
+++ b/Modules/_sqlite/blob.c
@@ -450,6 +450,12 @@ subscript_slice(pysqlite_Blob *self, PyObject *item)
         return PyBytes_FromStringAndSize(NULL, 0);
     }
 
+    if (step < 0) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Blob doesn't support slices with a negative step");
+        return NULL;
+    }
+
     if (step == 1) {
         return read_multiple(self, len, start);
     }
@@ -557,6 +563,13 @@ ass_subscript_slice(pysqlite_Blob *self, PyObject *item, 
PyObject *value)
         return 0;
     }
 
+    if (step < 0) {
+        PyErr_SetString(PyExc_ValueError,
+                        "Blob doesn't support slices with a negative step");
+        PyBuffer_Release(&vbuf);
+        return -1;
+    }
+
     int rc = -1;
     if (step == 1) {
         rc = inner_write(self, vbuf.buf, len, start);

_______________________________________________
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]

Reply via email to