Skip to content

gh-100370: fix OverflowError in sqlite3.Connection.blobopen for 32-bit builds #103902

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
May 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Lib/test/test_sqlite3/test_dbapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -1495,6 +1495,14 @@ def test_blob_closed_db_read(self):
"Cannot operate on a closed database",
blob.read)

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


@threading_helper.requires_working_threading()
class ThreadTests(unittest.TestCase):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fix potential :exc:`OverflowError` in :meth:`sqlite3.Connection.blobopen`
for 32-bit builds. Patch by Erlend E. Aasland.
9 changes: 4 additions & 5 deletions Modules/_sqlite/clinic/connection.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

26 changes: 22 additions & 4 deletions Modules/_sqlite/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,20 @@ autocommit_converter(PyObject *val, enum autocommit_mode *result)
return 0;
}

static int
sqlite3_int64_converter(PyObject *obj, sqlite3_int64 *result)
{
if (!PyLong_Check(obj)) {
PyErr_SetString(PyExc_TypeError, "expected 'int'");
return 0;
}
*result = _pysqlite_long_as_int64(obj);
if (PyErr_Occurred()) {
return 0;
}
return 1;
}

#define clinic_state() (pysqlite_get_state_by_type(Py_TYPE(self)))
#include "clinic/connection.c.h"
#undef clinic_state
Expand Down Expand Up @@ -188,8 +202,12 @@ class Autocommit_converter(CConverter):
type = "enum autocommit_mode"
converter = "autocommit_converter"

class sqlite3_int64_converter(CConverter):
type = "sqlite3_int64"
converter = "sqlite3_int64_converter"

[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=bc2aa6c7ba0c5f8f]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=dff8760fb1eba6a1]*/

// NB: This needs to be in sync with the sqlite3.connect docstring
/*[clinic input]
Expand Down Expand Up @@ -483,7 +501,7 @@ _sqlite3.Connection.blobopen as blobopen
Table name.
column as col: str
Column name.
row: int
row: sqlite3_int64
Row index.
/
*
Expand All @@ -497,8 +515,8 @@ Open and return a BLOB object.

static PyObject *
blobopen_impl(pysqlite_Connection *self, const char *table, const char *col,
int row, int readonly, const char *name)
/*[clinic end generated code: output=0c8e2e58516d0b5c input=fa73c83aa7a7ddee]*/
sqlite3_int64 row, int readonly, const char *name)
/*[clinic end generated code: output=6a02d43efb885d1c input=23576bd1108d8774]*/
{
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
return NULL;
Expand Down