mirror of https://github.com/python/cpython.git
Issue #17073: Fix some integer overflows in sqlite3 module.
This commit is contained in:
parent
d5327d95d2
commit
35c52b687f
|
@ -76,6 +76,25 @@ def mycoll(x, y):
|
||||||
except sqlite.OperationalError, e:
|
except sqlite.OperationalError, e:
|
||||||
self.assertEqual(e.args[0].lower(), "no such collation sequence: mycoll")
|
self.assertEqual(e.args[0].lower(), "no such collation sequence: mycoll")
|
||||||
|
|
||||||
|
def CheckCollationReturnsLargeInteger(self):
|
||||||
|
def mycoll(x, y):
|
||||||
|
# reverse order
|
||||||
|
return -((x > y) - (x < y)) * 2**32
|
||||||
|
con = sqlite.connect(":memory:")
|
||||||
|
con.create_collation("mycoll", mycoll)
|
||||||
|
sql = """
|
||||||
|
select x from (
|
||||||
|
select 'a' as x
|
||||||
|
union
|
||||||
|
select 'b' as x
|
||||||
|
union
|
||||||
|
select 'c' as x
|
||||||
|
) order by x collate mycoll
|
||||||
|
"""
|
||||||
|
result = con.execute(sql).fetchall()
|
||||||
|
self.assertEqual(result, [('c',), ('b',), ('a',)],
|
||||||
|
msg="the expected order was not returned")
|
||||||
|
|
||||||
def CheckCollationRegisterTwice(self):
|
def CheckCollationRegisterTwice(self):
|
||||||
"""
|
"""
|
||||||
Register two different collation functions under the same name.
|
Register two different collation functions under the same name.
|
||||||
|
|
|
@ -374,14 +374,15 @@ def CheckAggrCheckAggrSum(self):
|
||||||
val = cur.fetchone()[0]
|
val = cur.fetchone()[0]
|
||||||
self.assertEqual(val, 60)
|
self.assertEqual(val, 60)
|
||||||
|
|
||||||
def authorizer_cb(action, arg1, arg2, dbname, source):
|
|
||||||
if action != sqlite.SQLITE_SELECT:
|
|
||||||
return sqlite.SQLITE_DENY
|
|
||||||
if arg2 == 'c2' or arg1 == 't2':
|
|
||||||
return sqlite.SQLITE_DENY
|
|
||||||
return sqlite.SQLITE_OK
|
|
||||||
|
|
||||||
class AuthorizerTests(unittest.TestCase):
|
class AuthorizerTests(unittest.TestCase):
|
||||||
|
@staticmethod
|
||||||
|
def authorizer_cb(action, arg1, arg2, dbname, source):
|
||||||
|
if action != sqlite.SQLITE_SELECT:
|
||||||
|
return sqlite.SQLITE_DENY
|
||||||
|
if arg2 == 'c2' or arg1 == 't2':
|
||||||
|
return sqlite.SQLITE_DENY
|
||||||
|
return sqlite.SQLITE_OK
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
self.con = sqlite.connect(":memory:")
|
self.con = sqlite.connect(":memory:")
|
||||||
self.con.executescript("""
|
self.con.executescript("""
|
||||||
|
@ -394,12 +395,12 @@ def setUp(self):
|
||||||
# For our security test:
|
# For our security test:
|
||||||
self.con.execute("select c2 from t2")
|
self.con.execute("select c2 from t2")
|
||||||
|
|
||||||
self.con.set_authorizer(authorizer_cb)
|
self.con.set_authorizer(self.authorizer_cb)
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def CheckTableAccess(self):
|
def test_table_access(self):
|
||||||
try:
|
try:
|
||||||
self.con.execute("select * from t2")
|
self.con.execute("select * from t2")
|
||||||
except sqlite.DatabaseError, e:
|
except sqlite.DatabaseError, e:
|
||||||
|
@ -408,7 +409,7 @@ def CheckTableAccess(self):
|
||||||
return
|
return
|
||||||
self.fail("should have raised an exception due to missing privileges")
|
self.fail("should have raised an exception due to missing privileges")
|
||||||
|
|
||||||
def CheckColumnAccess(self):
|
def test_column_access(self):
|
||||||
try:
|
try:
|
||||||
self.con.execute("select c2 from t1")
|
self.con.execute("select c2 from t1")
|
||||||
except sqlite.DatabaseError, e:
|
except sqlite.DatabaseError, e:
|
||||||
|
@ -417,11 +418,46 @@ def CheckColumnAccess(self):
|
||||||
return
|
return
|
||||||
self.fail("should have raised an exception due to missing privileges")
|
self.fail("should have raised an exception due to missing privileges")
|
||||||
|
|
||||||
|
class AuthorizerRaiseExceptionTests(AuthorizerTests):
|
||||||
|
@staticmethod
|
||||||
|
def authorizer_cb(action, arg1, arg2, dbname, source):
|
||||||
|
if action != sqlite.SQLITE_SELECT:
|
||||||
|
raise ValueError
|
||||||
|
if arg2 == 'c2' or arg1 == 't2':
|
||||||
|
raise ValueError
|
||||||
|
return sqlite.SQLITE_OK
|
||||||
|
|
||||||
|
class AuthorizerIllegalTypeTests(AuthorizerTests):
|
||||||
|
@staticmethod
|
||||||
|
def authorizer_cb(action, arg1, arg2, dbname, source):
|
||||||
|
if action != sqlite.SQLITE_SELECT:
|
||||||
|
return 0.0
|
||||||
|
if arg2 == 'c2' or arg1 == 't2':
|
||||||
|
return 0.0
|
||||||
|
return sqlite.SQLITE_OK
|
||||||
|
|
||||||
|
class AuthorizerLargeIntegerTests(AuthorizerTests):
|
||||||
|
@staticmethod
|
||||||
|
def authorizer_cb(action, arg1, arg2, dbname, source):
|
||||||
|
if action != sqlite.SQLITE_SELECT:
|
||||||
|
return 2**32
|
||||||
|
if arg2 == 'c2' or arg1 == 't2':
|
||||||
|
return 2**32
|
||||||
|
return sqlite.SQLITE_OK
|
||||||
|
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
function_suite = unittest.makeSuite(FunctionTests, "Check")
|
function_suite = unittest.makeSuite(FunctionTests, "Check")
|
||||||
aggregate_suite = unittest.makeSuite(AggregateTests, "Check")
|
aggregate_suite = unittest.makeSuite(AggregateTests, "Check")
|
||||||
authorizer_suite = unittest.makeSuite(AuthorizerTests, "Check")
|
authorizer_suite = unittest.makeSuite(AuthorizerTests)
|
||||||
return unittest.TestSuite((function_suite, aggregate_suite, authorizer_suite))
|
return unittest.TestSuite((
|
||||||
|
function_suite,
|
||||||
|
aggregate_suite,
|
||||||
|
authorizer_suite,
|
||||||
|
unittest.makeSuite(AuthorizerRaiseExceptionTests),
|
||||||
|
unittest.makeSuite(AuthorizerIllegalTypeTests),
|
||||||
|
unittest.makeSuite(AuthorizerLargeIntegerTests),
|
||||||
|
))
|
||||||
|
|
||||||
def test():
|
def test():
|
||||||
runner = unittest.TextTestRunner()
|
runner = unittest.TextTestRunner()
|
||||||
|
|
|
@ -202,6 +202,8 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #17073: Fix some integer overflows in sqlite3 module.
|
||||||
|
|
||||||
- Issue #6083: Fix multiple segmentation faults occured when PyArg_ParseTuple
|
- Issue #6083: Fix multiple segmentation faults occured when PyArg_ParseTuple
|
||||||
parses nested mutating sequence.
|
parses nested mutating sequence.
|
||||||
|
|
||||||
|
|
|
@ -538,39 +538,40 @@ PyObject* pysqlite_connection_rollback(pysqlite_Connection* self, PyObject* args
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _pysqlite_set_result(sqlite3_context* context, PyObject* py_val)
|
static int
|
||||||
|
_pysqlite_set_result(sqlite3_context* context, PyObject* py_val)
|
||||||
{
|
{
|
||||||
const char* buffer;
|
if (py_val == Py_None) {
|
||||||
Py_ssize_t buflen;
|
|
||||||
PyObject* stringval;
|
|
||||||
|
|
||||||
if ((!py_val) || PyErr_Occurred()) {
|
|
||||||
sqlite3_result_null(context);
|
|
||||||
} else if (py_val == Py_None) {
|
|
||||||
sqlite3_result_null(context);
|
sqlite3_result_null(context);
|
||||||
} else if (PyInt_Check(py_val)) {
|
} else if (PyInt_Check(py_val)) {
|
||||||
sqlite3_result_int64(context, (sqlite_int64)PyInt_AsLong(py_val));
|
sqlite3_result_int64(context, (sqlite_int64)PyInt_AsLong(py_val));
|
||||||
} else if (PyLong_Check(py_val)) {
|
} else if (PyLong_Check(py_val)) {
|
||||||
sqlite3_result_int64(context, PyLong_AsLongLong(py_val));
|
sqlite_int64 value = _pysqlite_long_as_int64(py_val);
|
||||||
|
if (value == -1 && PyErr_Occurred())
|
||||||
|
return -1;
|
||||||
|
sqlite3_result_int64(context, value);
|
||||||
} else if (PyFloat_Check(py_val)) {
|
} else if (PyFloat_Check(py_val)) {
|
||||||
sqlite3_result_double(context, PyFloat_AsDouble(py_val));
|
sqlite3_result_double(context, PyFloat_AsDouble(py_val));
|
||||||
} else if (PyBuffer_Check(py_val)) {
|
} else if (PyBuffer_Check(py_val)) {
|
||||||
|
const char* buffer;
|
||||||
|
Py_ssize_t buflen;
|
||||||
if (PyObject_AsCharBuffer(py_val, &buffer, &buflen) != 0) {
|
if (PyObject_AsCharBuffer(py_val, &buffer, &buflen) != 0) {
|
||||||
PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");
|
PyErr_SetString(PyExc_ValueError, "could not convert BLOB to buffer");
|
||||||
} else {
|
return -1;
|
||||||
sqlite3_result_blob(context, buffer, buflen, SQLITE_TRANSIENT);
|
|
||||||
}
|
}
|
||||||
|
sqlite3_result_blob(context, buffer, buflen, SQLITE_TRANSIENT);
|
||||||
} else if (PyString_Check(py_val)) {
|
} else if (PyString_Check(py_val)) {
|
||||||
sqlite3_result_text(context, PyString_AsString(py_val), -1, SQLITE_TRANSIENT);
|
sqlite3_result_text(context, PyString_AsString(py_val), -1, SQLITE_TRANSIENT);
|
||||||
} else if (PyUnicode_Check(py_val)) {
|
} else if (PyUnicode_Check(py_val)) {
|
||||||
stringval = PyUnicode_AsUTF8String(py_val);
|
PyObject * stringval = PyUnicode_AsUTF8String(py_val);
|
||||||
if (stringval) {
|
if (!stringval)
|
||||||
sqlite3_result_text(context, PyString_AsString(stringval), -1, SQLITE_TRANSIENT);
|
return -1;
|
||||||
Py_DECREF(stringval);
|
sqlite3_result_text(context, PyString_AsString(stringval), -1, SQLITE_TRANSIENT);
|
||||||
}
|
Py_DECREF(stringval);
|
||||||
} else {
|
} else {
|
||||||
/* TODO: raise error */
|
return -1;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_value** argv)
|
PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_value** argv)
|
||||||
|
@ -580,7 +581,6 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_
|
||||||
sqlite3_value* cur_value;
|
sqlite3_value* cur_value;
|
||||||
PyObject* cur_py_value;
|
PyObject* cur_py_value;
|
||||||
const char* val_str;
|
const char* val_str;
|
||||||
sqlite_int64 val_int;
|
|
||||||
Py_ssize_t buflen;
|
Py_ssize_t buflen;
|
||||||
void* raw_buffer;
|
void* raw_buffer;
|
||||||
|
|
||||||
|
@ -593,11 +593,7 @@ PyObject* _pysqlite_build_py_params(sqlite3_context *context, int argc, sqlite3_
|
||||||
cur_value = argv[i];
|
cur_value = argv[i];
|
||||||
switch (sqlite3_value_type(argv[i])) {
|
switch (sqlite3_value_type(argv[i])) {
|
||||||
case SQLITE_INTEGER:
|
case SQLITE_INTEGER:
|
||||||
val_int = sqlite3_value_int64(cur_value);
|
cur_py_value = _pysqlite_long_from_int64(sqlite3_value_int64(cur_value));
|
||||||
if(val_int < LONG_MIN || val_int > LONG_MAX)
|
|
||||||
cur_py_value = PyLong_FromLongLong(val_int);
|
|
||||||
else
|
|
||||||
cur_py_value = PyInt_FromLong((long)val_int);
|
|
||||||
break;
|
break;
|
||||||
case SQLITE_FLOAT:
|
case SQLITE_FLOAT:
|
||||||
cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value));
|
cur_py_value = PyFloat_FromDouble(sqlite3_value_double(cur_value));
|
||||||
|
@ -648,6 +644,7 @@ void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value**
|
||||||
PyObject* args;
|
PyObject* args;
|
||||||
PyObject* py_func;
|
PyObject* py_func;
|
||||||
PyObject* py_retval = NULL;
|
PyObject* py_retval = NULL;
|
||||||
|
int ok;
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
PyGILState_STATE threadstate;
|
PyGILState_STATE threadstate;
|
||||||
|
@ -663,10 +660,12 @@ void _pysqlite_func_callback(sqlite3_context* context, int argc, sqlite3_value**
|
||||||
Py_DECREF(args);
|
Py_DECREF(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ok = 0;
|
||||||
if (py_retval) {
|
if (py_retval) {
|
||||||
_pysqlite_set_result(context, py_retval);
|
ok = _pysqlite_set_result(context, py_retval) == 0;
|
||||||
Py_DECREF(py_retval);
|
Py_DECREF(py_retval);
|
||||||
} else {
|
}
|
||||||
|
if (!ok) {
|
||||||
if (_enable_callback_tracebacks) {
|
if (_enable_callback_tracebacks) {
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
} else {
|
} else {
|
||||||
|
@ -746,8 +745,9 @@ static void _pysqlite_step_callback(sqlite3_context *context, int argc, sqlite3_
|
||||||
|
|
||||||
void _pysqlite_final_callback(sqlite3_context* context)
|
void _pysqlite_final_callback(sqlite3_context* context)
|
||||||
{
|
{
|
||||||
PyObject* function_result = NULL;
|
PyObject* function_result;
|
||||||
PyObject** aggregate_instance;
|
PyObject** aggregate_instance;
|
||||||
|
int ok;
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
PyGILState_STATE threadstate;
|
PyGILState_STATE threadstate;
|
||||||
|
@ -764,21 +764,23 @@ void _pysqlite_final_callback(sqlite3_context* context)
|
||||||
}
|
}
|
||||||
|
|
||||||
function_result = PyObject_CallMethod(*aggregate_instance, "finalize", "");
|
function_result = PyObject_CallMethod(*aggregate_instance, "finalize", "");
|
||||||
if (!function_result) {
|
Py_DECREF(*aggregate_instance);
|
||||||
|
|
||||||
|
ok = 0;
|
||||||
|
if (function_result) {
|
||||||
|
ok = _pysqlite_set_result(context, function_result) == 0;
|
||||||
|
Py_DECREF(function_result);
|
||||||
|
}
|
||||||
|
if (!ok) {
|
||||||
if (_enable_callback_tracebacks) {
|
if (_enable_callback_tracebacks) {
|
||||||
PyErr_Print();
|
PyErr_Print();
|
||||||
} else {
|
} else {
|
||||||
PyErr_Clear();
|
PyErr_Clear();
|
||||||
}
|
}
|
||||||
_sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1);
|
_sqlite3_result_error(context, "user-defined aggregate's 'finalize' method raised error", -1);
|
||||||
} else {
|
|
||||||
_pysqlite_set_result(context, function_result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
error:
|
error:
|
||||||
Py_XDECREF(*aggregate_instance);
|
|
||||||
Py_XDECREF(function_result);
|
|
||||||
|
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
PyGILState_Release(threadstate);
|
PyGILState_Release(threadstate);
|
||||||
#endif
|
#endif
|
||||||
|
@ -935,7 +937,9 @@ static int _authorizer_callback(void* user_arg, int action, const char* arg1, co
|
||||||
rc = SQLITE_DENY;
|
rc = SQLITE_DENY;
|
||||||
} else {
|
} else {
|
||||||
if (PyInt_Check(ret)) {
|
if (PyInt_Check(ret)) {
|
||||||
rc = (int)PyInt_AsLong(ret);
|
rc = _PyInt_AsInt(ret);
|
||||||
|
if (rc == -1 && PyErr_Occurred())
|
||||||
|
rc = SQLITE_DENY;
|
||||||
} else {
|
} else {
|
||||||
rc = SQLITE_DENY;
|
rc = SQLITE_DENY;
|
||||||
}
|
}
|
||||||
|
@ -967,7 +971,7 @@ static int _progress_handler(void* user_arg)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* abort query if error occurred */
|
/* abort query if error occurred */
|
||||||
rc = 1;
|
rc = 1;
|
||||||
} else {
|
} else {
|
||||||
rc = (int)PyObject_IsTrue(ret);
|
rc = (int)PyObject_IsTrue(ret);
|
||||||
Py_DECREF(ret);
|
Py_DECREF(ret);
|
||||||
|
@ -1337,6 +1341,7 @@ pysqlite_collation_callback(
|
||||||
PyGILState_STATE gilstate;
|
PyGILState_STATE gilstate;
|
||||||
#endif
|
#endif
|
||||||
PyObject* retval = NULL;
|
PyObject* retval = NULL;
|
||||||
|
long longval;
|
||||||
int result = 0;
|
int result = 0;
|
||||||
#ifdef WITH_THREAD
|
#ifdef WITH_THREAD
|
||||||
gilstate = PyGILState_Ensure();
|
gilstate = PyGILState_Ensure();
|
||||||
|
@ -1360,10 +1365,17 @@ pysqlite_collation_callback(
|
||||||
goto finally;
|
goto finally;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = PyInt_AsLong(retval);
|
longval = PyLong_AsLongAndOverflow(retval, &result);
|
||||||
if (PyErr_Occurred()) {
|
if (longval == -1 && PyErr_Occurred()) {
|
||||||
|
PyErr_Clear();
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
|
else if (!result) {
|
||||||
|
if (longval > 0)
|
||||||
|
result = 1;
|
||||||
|
else if (longval < 0)
|
||||||
|
result = -1;
|
||||||
|
}
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
Py_XDECREF(string1);
|
Py_XDECREF(string1);
|
||||||
|
|
|
@ -26,14 +26,6 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "sqlitecompat.h"
|
#include "sqlitecompat.h"
|
||||||
|
|
||||||
/* used to decide wether to call PyInt_FromLong or PyLong_FromLongLong */
|
|
||||||
#ifndef INT32_MIN
|
|
||||||
#define INT32_MIN (-2147483647 - 1)
|
|
||||||
#endif
|
|
||||||
#ifndef INT32_MAX
|
|
||||||
#define INT32_MAX 2147483647
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self);
|
PyObject* pysqlite_cursor_iternext(pysqlite_Cursor* self);
|
||||||
|
|
||||||
static char* errmsg_fetch_across_rollback = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from.";
|
static char* errmsg_fetch_across_rollback = "Cursor needed to be reset because of commit/rollback and can no longer be fetched from.";
|
||||||
|
@ -307,7 +299,6 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
|
||||||
PyObject* row;
|
PyObject* row;
|
||||||
PyObject* item = NULL;
|
PyObject* item = NULL;
|
||||||
int coltype;
|
int coltype;
|
||||||
PY_LONG_LONG intval;
|
|
||||||
PyObject* converter;
|
PyObject* converter;
|
||||||
PyObject* converted;
|
PyObject* converted;
|
||||||
Py_ssize_t nbytes;
|
Py_ssize_t nbytes;
|
||||||
|
@ -366,12 +357,7 @@ PyObject* _pysqlite_fetch_one_row(pysqlite_Cursor* self)
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
converted = Py_None;
|
converted = Py_None;
|
||||||
} else if (coltype == SQLITE_INTEGER) {
|
} else if (coltype == SQLITE_INTEGER) {
|
||||||
intval = sqlite3_column_int64(self->statement->st, i);
|
converted = _pysqlite_long_from_int64(sqlite3_column_int64(self->statement->st, i));
|
||||||
if (intval < INT32_MIN || intval > INT32_MAX) {
|
|
||||||
converted = PyLong_FromLongLong(intval);
|
|
||||||
} else {
|
|
||||||
converted = PyInt_FromLong((long)intval);
|
|
||||||
}
|
|
||||||
} else if (coltype == SQLITE_FLOAT) {
|
} else if (coltype == SQLITE_FLOAT) {
|
||||||
converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i));
|
converted = PyFloat_FromDouble(sqlite3_column_double(self->statement->st, i));
|
||||||
} else if (coltype == SQLITE_TEXT) {
|
} else if (coltype == SQLITE_TEXT) {
|
||||||
|
@ -466,7 +452,6 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
|
||||||
PyObject* func_args;
|
PyObject* func_args;
|
||||||
PyObject* result;
|
PyObject* result;
|
||||||
int numcols;
|
int numcols;
|
||||||
PY_LONG_LONG lastrowid;
|
|
||||||
int statement_type;
|
int statement_type;
|
||||||
PyObject* descriptor;
|
PyObject* descriptor;
|
||||||
PyObject* second_argument = NULL;
|
PyObject* second_argument = NULL;
|
||||||
|
@ -747,10 +732,11 @@ PyObject* _pysqlite_query_execute(pysqlite_Cursor* self, int multiple, PyObject*
|
||||||
|
|
||||||
Py_DECREF(self->lastrowid);
|
Py_DECREF(self->lastrowid);
|
||||||
if (!multiple && statement_type == STATEMENT_INSERT) {
|
if (!multiple && statement_type == STATEMENT_INSERT) {
|
||||||
|
sqlite3_int64 lastrowid;
|
||||||
Py_BEGIN_ALLOW_THREADS
|
Py_BEGIN_ALLOW_THREADS
|
||||||
lastrowid = sqlite3_last_insert_rowid(self->connection->db);
|
lastrowid = sqlite3_last_insert_rowid(self->connection->db);
|
||||||
Py_END_ALLOW_THREADS
|
Py_END_ALLOW_THREADS
|
||||||
self->lastrowid = PyInt_FromLong((long)lastrowid);
|
self->lastrowid = _pysqlite_long_from_int64(lastrowid);
|
||||||
} else {
|
} else {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
self->lastrowid = Py_None;
|
self->lastrowid = Py_None;
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include "connection.h"
|
#include "connection.h"
|
||||||
#include "microprotocols.h"
|
#include "microprotocols.h"
|
||||||
#include "prepare_protocol.h"
|
#include "prepare_protocol.h"
|
||||||
|
#include "util.h"
|
||||||
#include "sqlitecompat.h"
|
#include "sqlitecompat.h"
|
||||||
|
|
||||||
/* prototypes */
|
/* prototypes */
|
||||||
|
@ -101,8 +102,6 @@ int pysqlite_statement_create(pysqlite_Statement* self, pysqlite_Connection* con
|
||||||
int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter, int allow_8bit_chars)
|
int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObject* parameter, int allow_8bit_chars)
|
||||||
{
|
{
|
||||||
int rc = SQLITE_OK;
|
int rc = SQLITE_OK;
|
||||||
long longval;
|
|
||||||
PY_LONG_LONG longlongval;
|
|
||||||
const char* buffer;
|
const char* buffer;
|
||||||
char* string;
|
char* string;
|
||||||
Py_ssize_t buflen;
|
Py_ssize_t buflen;
|
||||||
|
@ -153,15 +152,19 @@ int pysqlite_statement_bind_parameter(pysqlite_Statement* self, int pos, PyObjec
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (paramtype) {
|
switch (paramtype) {
|
||||||
case TYPE_INT:
|
case TYPE_INT: {
|
||||||
longval = PyInt_AsLong(parameter);
|
long longval = PyInt_AsLong(parameter);
|
||||||
rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longval);
|
rc = sqlite3_bind_int64(self->st, pos, longval);
|
||||||
break;
|
break;
|
||||||
case TYPE_LONG:
|
}
|
||||||
longlongval = PyLong_AsLongLong(parameter);
|
case TYPE_LONG: {
|
||||||
/* in the overflow error case, longlongval is -1, and an exception is set */
|
sqlite_int64 value = _pysqlite_long_as_int64(parameter);
|
||||||
rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)longlongval);
|
if (value == -1 && PyErr_Occurred())
|
||||||
|
rc = -1;
|
||||||
|
else
|
||||||
|
rc = sqlite3_bind_int64(self->st, pos, (sqlite_int64)value);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
case TYPE_FLOAT:
|
case TYPE_FLOAT:
|
||||||
rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter));
|
rc = sqlite3_bind_double(self->st, pos, PyFloat_AsDouble(parameter));
|
||||||
break;
|
break;
|
||||||
|
@ -198,7 +201,7 @@ static int _need_adapt(PyObject* obj)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PyInt_CheckExact(obj) || PyLong_CheckExact(obj)
|
if (PyInt_CheckExact(obj) || PyLong_CheckExact(obj)
|
||||||
|| PyFloat_CheckExact(obj) || PyString_CheckExact(obj)
|
|| PyFloat_CheckExact(obj) || PyString_CheckExact(obj)
|
||||||
|| PyUnicode_CheckExact(obj) || PyBuffer_Check(obj)) {
|
|| PyUnicode_CheckExact(obj) || PyBuffer_Check(obj)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -104,3 +104,69 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st)
|
||||||
return errorcode;
|
return errorcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WORDS_BIGENDIAN
|
||||||
|
# define IS_LITTLE_ENDIAN 0
|
||||||
|
#else
|
||||||
|
# define IS_LITTLE_ENDIAN 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
PyObject *
|
||||||
|
_pysqlite_long_from_int64(sqlite3_int64 value)
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
# if SIZEOF_LONG_LONG < 8
|
||||||
|
if (value > PY_LLONG_MAX || value < PY_LLONG_MIN) {
|
||||||
|
return _PyLong_FromByteArray(&value, sizeof(value),
|
||||||
|
IS_LITTLE_ENDIAN, 1 /* signed */);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
# if SIZEOF_LONG < SIZEOF_LONG_LONG
|
||||||
|
if (value > LONG_MAX || value < LONG_MIN)
|
||||||
|
return PyLong_FromLongLong(value);
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# if SIZEOF_LONG < 8
|
||||||
|
if (value > LONG_MAX || value < LONG_MIN) {
|
||||||
|
return _PyLong_FromByteArray(&value, sizeof(value),
|
||||||
|
IS_LITTLE_ENDIAN, 1 /* signed */);
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
return PyInt_FromLong(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_int64
|
||||||
|
_pysqlite_long_as_int64(PyObject * py_val)
|
||||||
|
{
|
||||||
|
int overflow;
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
PY_LONG_LONG value = PyLong_AsLongLongAndOverflow(py_val, &overflow);
|
||||||
|
#else
|
||||||
|
long value = PyLong_AsLongAndOverflow(py_val, &overflow);
|
||||||
|
#endif
|
||||||
|
if (value == -1 && PyErr_Occurred())
|
||||||
|
return -1;
|
||||||
|
if (!overflow) {
|
||||||
|
#ifdef HAVE_LONG_LONG
|
||||||
|
# if SIZEOF_LONG_LONG > 8
|
||||||
|
if (-0x8000000000000000LL <= value && value <= 0x7FFFFFFFFFFFFFFFLL)
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# if SIZEOF_LONG > 8
|
||||||
|
if (-0x8000000000000000L <= value && value <= 0x7FFFFFFFFFFFFFFFL)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
else if (sizeof(value) < sizeof(sqlite3_int64)) {
|
||||||
|
sqlite3_int64 int64val;
|
||||||
|
if (_PyLong_AsByteArray((PyLongObject *)py_val,
|
||||||
|
(unsigned char *)&int64val, sizeof(int64val),
|
||||||
|
IS_LITTLE_ENDIAN, 1 /* signed */) >= 0) {
|
||||||
|
return int64val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PyErr_SetString(PyExc_OverflowError,
|
||||||
|
"Python int too large to convert to SQLite INTEGER");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
|
@ -35,4 +35,8 @@ int pysqlite_step(sqlite3_stmt* statement, pysqlite_Connection* connection);
|
||||||
* Returns the error code (0 means no error occurred).
|
* Returns the error code (0 means no error occurred).
|
||||||
*/
|
*/
|
||||||
int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st);
|
int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st);
|
||||||
|
|
||||||
|
PyObject * _pysqlite_long_from_int64(sqlite3_int64 value);
|
||||||
|
sqlite3_int64 _pysqlite_long_as_int64(PyObject * value);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue