From 83cdcc0dadb4a044d7c10b0a64a6853d0889ee74 Mon Sep 17 00:00:00 2001 From: Jiseok CHOI Date: Thu, 4 Jun 2026 22:41:47 +0900 Subject: [PATCH] gh-150913: Fix sqlite3.Blob validation for empty slice assignment (GH-150915) ass_subscript_slice() returned early when the computed slice length was zero, bypassing validation performed for non-empty slices. (cherry picked from commit fc9c4db1302f8be7527e70cf0938b629985a1d72) Co-authored-by: Jiseok CHOI --- Lib/test/test_sqlite3/test_dbapi.py | 12 ++++++++++++ ...26-06-04-21-49-18.gh-issue-150913.EmptyBl.rst | 3 +++ Modules/_sqlite/blob.c | 16 ++++++++++------ 3 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-06-04-21-49-18.gh-issue-150913.EmptyBl.rst diff --git a/Lib/test/test_sqlite3/test_dbapi.py b/Lib/test/test_sqlite3/test_dbapi.py index 73b40e82a96811f..5f6cb527955ca17 100644 --- a/Lib/test/test_sqlite3/test_dbapi.py +++ b/Lib/test/test_sqlite3/test_dbapi.py @@ -1400,6 +1400,18 @@ def test_blob_set_empty_slice(self): self.blob[0:0] = b"" self.assertEqual(self.blob[:], self.data) + def test_blob_set_empty_slice_wrong_type(self): + with self.assertRaises(TypeError): + self.blob[5:5] = None + + def test_blob_set_empty_slice_wrong_size(self): + with self.assertRaisesRegex(IndexError, "wrong size"): + self.blob[5:5] = b"123" + + def test_blob_set_empty_slice_correct(self): + self.blob[5:5] = b"" + self.assertEqual(self.blob[:], self.data) + def test_blob_set_slice_with_skip(self): self.blob[0:10:2] = b"12345" actual = self.cx.execute("select b from test").fetchone()[0] diff --git a/Misc/NEWS.d/next/Library/2026-06-04-21-49-18.gh-issue-150913.EmptyBl.rst b/Misc/NEWS.d/next/Library/2026-06-04-21-49-18.gh-issue-150913.EmptyBl.rst new file mode 100644 index 000000000000000..f95a6ee6ee15bf7 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-06-04-21-49-18.gh-issue-150913.EmptyBl.rst @@ -0,0 +1,3 @@ +Fix :class:`sqlite3.Blob` slice assignment to raise +:exc:`TypeError` and :exc:`IndexError` for type and size mismatches +respectively, even when the target slice is empty. diff --git a/Modules/_sqlite/blob.c b/Modules/_sqlite/blob.c index 2cc62751054278f..d81784409e5d91a 100644 --- a/Modules/_sqlite/blob.c +++ b/Modules/_sqlite/blob.c @@ -531,21 +531,25 @@ ass_subscript_slice(pysqlite_Blob *self, PyObject *item, PyObject *value) return -1; } - if (len == 0) { - return 0; - } - Py_buffer vbuf; if (PyObject_GetBuffer(value, &vbuf, PyBUF_SIMPLE) < 0) { return -1; } - int rc = -1; if (vbuf.len != len) { PyErr_SetString(PyExc_IndexError, "Blob slice assignment is wrong size"); + PyBuffer_Release(&vbuf); + return -1; } - else if (step == 1) { + + if (len == 0) { + PyBuffer_Release(&vbuf); + return 0; + } + + int rc = -1; + if (step == 1) { rc = inner_write(self, vbuf.buf, len, start); } else {