Skip to content

Commit a05bad3

Browse files
gh-100370: fix OverflowError in sqlite3.Connection.blobopen for 32-bit builds (#103902)
1 parent cab1298 commit a05bad3

File tree

4 files changed

+36
-9
lines changed

4 files changed

+36
-9
lines changed

Lib/test/test_sqlite3/test_dbapi.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,14 @@ def test_blob_closed_db_read(self):
14951495
"Cannot operate on a closed database",
14961496
blob.read)
14971497

1498+
def test_blob_32bit_rowid(self):
1499+
# gh-100370: we should not get an OverflowError for 32-bit rowids
1500+
with memory_database() as cx:
1501+
rowid = 2**32
1502+
cx.execute("create table t(t blob)")
1503+
cx.execute("insert into t(rowid, t) values (?, zeroblob(1))", (rowid,))
1504+
cx.blobopen('t', 't', rowid)
1505+
14981506

14991507
@threading_helper.requires_working_threading()
15001508
class ThreadTests(unittest.TestCase):
Lines changed: 2 additions & 0 deletions
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

Lines changed: 4 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Modules/_sqlite/connection.c

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,20 @@ autocommit_converter(PyObject *val, enum autocommit_mode *result)
118118
return 0;
119119
}
120120

121+
static int
122+
sqlite3_int64_converter(PyObject *obj, sqlite3_int64 *result)
123+
{
124+
if (!PyLong_Check(obj)) {
125+
PyErr_SetString(PyExc_TypeError, "expected 'int'");
126+
return 0;
127+
}
128+
*result = _pysqlite_long_as_int64(obj);
129+
if (PyErr_Occurred()) {
130+
return 0;
131+
}
132+
return 1;
133+
}
134+
121135
#define clinic_state() (pysqlite_get_state_by_type(Py_TYPE(self)))
122136
#include "clinic/connection.c.h"
123137
#undef clinic_state
@@ -188,8 +202,12 @@ class Autocommit_converter(CConverter):
188202
type = "enum autocommit_mode"
189203
converter = "autocommit_converter"
190204
205+
class sqlite3_int64_converter(CConverter):
206+
type = "sqlite3_int64"
207+
converter = "sqlite3_int64_converter"
208+
191209
[python start generated code]*/
192-
/*[python end generated code: output=da39a3ee5e6b4b0d input=bc2aa6c7ba0c5f8f]*/
210+
/*[python end generated code: output=da39a3ee5e6b4b0d input=dff8760fb1eba6a1]*/
193211

194212
// NB: This needs to be in sync with the sqlite3.connect docstring
195213
/*[clinic input]
@@ -483,7 +501,7 @@ _sqlite3.Connection.blobopen as blobopen
483501
Table name.
484502
column as col: str
485503
Column name.
486-
row: int
504+
row: sqlite3_int64
487505
Row index.
488506
/
489507
*
@@ -497,8 +515,8 @@ Open and return a BLOB object.
497515

498516
static PyObject *
499517
blobopen_impl(pysqlite_Connection *self, const char *table, const char *col,
500-
int row, int readonly, const char *name)
501-
/*[clinic end generated code: output=0c8e2e58516d0b5c input=fa73c83aa7a7ddee]*/
518+
sqlite3_int64 row, int readonly, const char *name)
519+
/*[clinic end generated code: output=6a02d43efb885d1c input=23576bd1108d8774]*/
502520
{
503521
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
504522
return NULL;

0 commit comments

Comments
 (0)