mirror of
https://github.com/python/cpython.git
synced 2025-10-01 21:02:15 +00:00
[3.11] gh-100370: fix OverflowError in sqlite3.Connection.blobopen for 32-bit builds (#103902) (#104285)
This commit is contained in:
parent
19abf691fe
commit
681d5028bd
4 changed files with 36 additions and 9 deletions
|
@ -1461,6 +1461,14 @@ class BlobTests(unittest.TestCase):
|
||||||
"Cannot operate on a closed database",
|
"Cannot operate on a closed database",
|
||||||
blob.read)
|
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()
|
@threading_helper.requires_working_threading()
|
||||||
class ThreadTests(unittest.TestCase):
|
class ThreadTests(unittest.TestCase):
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix potential :exc:`OverflowError` in :meth:`sqlite3.Connection.blobopen`
|
||||||
|
for 32-bit builds. Patch by Erlend E. Aasland.
|
9
Modules/_sqlite/clinic/connection.c.h
generated
9
Modules/_sqlite/clinic/connection.c.h
generated
|
@ -162,7 +162,7 @@ PyDoc_STRVAR(blobopen__doc__,
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
blobopen_impl(pysqlite_Connection *self, const char *table, const char *col,
|
blobopen_impl(pysqlite_Connection *self, const char *table, const char *col,
|
||||||
int row, int readonly, const char *name);
|
sqlite3_int64 row, int readonly, const char *name);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
blobopen(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
blobopen(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
|
@ -174,7 +174,7 @@ blobopen(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyO
|
||||||
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3;
|
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3;
|
||||||
const char *table;
|
const char *table;
|
||||||
const char *col;
|
const char *col;
|
||||||
int row;
|
sqlite3_int64 row;
|
||||||
int readonly = 0;
|
int readonly = 0;
|
||||||
const char *name = "main";
|
const char *name = "main";
|
||||||
|
|
||||||
|
@ -208,8 +208,7 @@ blobopen(pysqlite_Connection *self, PyObject *const *args, Py_ssize_t nargs, PyO
|
||||||
PyErr_SetString(PyExc_ValueError, "embedded null character");
|
PyErr_SetString(PyExc_ValueError, "embedded null character");
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
row = _PyLong_AsInt(args[2]);
|
if (!sqlite3_int64_converter(args[2], &row)) {
|
||||||
if (row == -1 && PyErr_Occurred()) {
|
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
if (!noptargs) {
|
if (!noptargs) {
|
||||||
|
@ -1237,4 +1236,4 @@ exit:
|
||||||
#ifndef DESERIALIZE_METHODDEF
|
#ifndef DESERIALIZE_METHODDEF
|
||||||
#define DESERIALIZE_METHODDEF
|
#define DESERIALIZE_METHODDEF
|
||||||
#endif /* !defined(DESERIALIZE_METHODDEF) */
|
#endif /* !defined(DESERIALIZE_METHODDEF) */
|
||||||
/*[clinic end generated code: output=8818c1c3ec9425aa input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=67e5b3dbade4a15b input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -92,6 +92,20 @@ isolation_level_converter(PyObject *str_or_none, const char **result)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)))
|
#define clinic_state() (pysqlite_get_state_by_type(Py_TYPE(self)))
|
||||||
#include "clinic/connection.c.h"
|
#include "clinic/connection.c.h"
|
||||||
#undef clinic_state
|
#undef clinic_state
|
||||||
|
@ -137,8 +151,12 @@ class IsolationLevel_converter(CConverter):
|
||||||
type = "const char *"
|
type = "const char *"
|
||||||
converter = "isolation_level_converter"
|
converter = "isolation_level_converter"
|
||||||
|
|
||||||
|
class sqlite3_int64_converter(CConverter):
|
||||||
|
type = "sqlite3_int64"
|
||||||
|
converter = "sqlite3_int64_converter"
|
||||||
|
|
||||||
[python start generated code]*/
|
[python start generated code]*/
|
||||||
/*[python end generated code: output=da39a3ee5e6b4b0d input=cbcfe85b253061c2]*/
|
/*[python end generated code: output=da39a3ee5e6b4b0d input=e9bee126e0500e61]*/
|
||||||
|
|
||||||
// NB: This needs to be in sync with the sqlite3.connect docstring
|
// NB: This needs to be in sync with the sqlite3.connect docstring
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
|
@ -401,7 +419,7 @@ _sqlite3.Connection.blobopen as blobopen
|
||||||
Table name.
|
Table name.
|
||||||
column as col: str
|
column as col: str
|
||||||
Column name.
|
Column name.
|
||||||
row: int
|
row: sqlite3_int64
|
||||||
Row index.
|
Row index.
|
||||||
/
|
/
|
||||||
*
|
*
|
||||||
|
@ -415,8 +433,8 @@ Open and return a BLOB object.
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
blobopen_impl(pysqlite_Connection *self, const char *table, const char *col,
|
blobopen_impl(pysqlite_Connection *self, const char *table, const char *col,
|
||||||
int row, int readonly, const char *name)
|
sqlite3_int64 row, int readonly, const char *name)
|
||||||
/*[clinic end generated code: output=0c8e2e58516d0b5c input=1e7052516acfc94d]*/
|
/*[clinic end generated code: output=6a02d43efb885d1c input=4180b11a0591d80d]*/
|
||||||
{
|
{
|
||||||
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
if (!pysqlite_check_thread(self) || !pysqlite_check_connection(self)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue