Skip to content

Commit 681d502

Browse files
[3.11] gh-100370: fix OverflowError in sqlite3.Connection.blobopen for 32-bit builds (#103902) (#104285)
1 parent 19abf69 commit 681d502

File tree

4 files changed

+36
-9
lines changed

4 files changed

+36
-9
lines changed

Lib/test/test_sqlite3/test_dbapi.py

+8
Original file line numberDiff line numberDiff line change
@@ -1461,6 +1461,14 @@ def test_blob_closed_db_read(self):
14611461
"Cannot operate on a closed database",
14621462
blob.read)
14631463

1464+
def test_blob_32bit_rowid(self):
1465+
# gh-100370: we should not get an OverflowError for 32-bit rowids
1466+
with memory_database() as cx:
1467+
rowid = 2**32
1468+
cx.execute("create table t(t blob)")
1469+
cx.execute("insert into t(rowid, t) values (?, zeroblob(1))", (rowid,))
1470+
cx.blobopen('t', 't', rowid)
1471+
14641472

14651473
@threading_helper.requires_working_threading()
14661474
class ThreadTests(unittest.TestCase):
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix potential :exc:`OverflowError` in :meth:`sqlite3.Connection.blobopen`
2+
for 32-bit builds. Patch by Erlend E. Aasland.

Modules/_sqlite/clinic/connection.c.h

+4-5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/_sqlite/connection.c

+22-4
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,20 @@ isolation_level_converter(PyObject *str_or_none, const char **result)
9292
return 1;
9393
}
9494

95+
static int
96+
sqlite3_int64_converter(PyObject *obj, sqlite3_int64 *result)
97+
{
98+
if (!PyLong_Check(obj)) {
99+
PyErr_SetString(PyExc_TypeError, "expected 'int'");
100+
return 0;
101+
}
102+
*result = _pysqlite_long_as_int64(obj);
103+
if (PyErr_Occurred()) {
104+
return 0;
105+
}
106+
return 1;
107+
}
108+
95109
#define clinic_state() (pysqlite_get_state_by_type(Py_TYPE(self)))
96110
#include "clinic/connection.c.h"
97111
#undef clinic_state
@@ -137,8 +151,12 @@ class IsolationLevel_converter(CConverter):
137151
type = "const char *"
138152
converter = "isolation_level_converter"
139153
154+
class sqlite3_int64_converter(CConverter):
155+
type = "sqlite3_int64"
156+
converter = "sqlite3_int64_converter"
157+
140158
[python start generated code]*/
141-
/*[python end generated code: output=da39a3ee5e6b4b0d input=cbcfe85b253061c2]*/
159+
/*[python end generated code: output=da39a3ee5e6b4b0d input=e9bee126e0500e61]*/
142160

143161
// NB: This needs to be in sync with the sqlite3.connect docstring
144162
/*[clinic input]
@@ -401,7 +419,7 @@ _sqlite3.Connection.blobopen as blobopen
401419
Table name.
402420
column as col: str
403421
Column name.
404-
row: int
422+
row: sqlite3_int64
405423
Row index.
406424
/
407425
*
@@ -415,8 +433,8 @@ Open and return a BLOB object.
415433

416434
static PyObject *
417435
blobopen_impl(pysqlite_Connection *self, const char *table, const char *col,
418-
int row, int readonly, const char *name)
419-
/*[clinic end generated code: output=0c8e2e58516d0b5c input=1e7052516acfc94d]*/
436+
sqlite3_int64 row, int readonly, const char *name)
437+
/*[clinic end generated code: output=6a02d43efb885d1c input=4180b11a0591d80d]*/
420438
{
421439
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
422440
return NULL;

0 commit comments

Comments
 (0)