diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2013-02-07 15:01:47 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2013-02-07 15:01:47 (GMT) |
commit | 3cf96ac2484d093bea17610480efd0e88301f72a (patch) | |
tree | bb932dd53295a2214a1a208141ecf4793cb153be /Modules/_sqlite/util.c | |
parent | 3fd4ab356d76b048f2dbd25797fec87f68dd7f73 (diff) | |
download | cpython-3cf96ac2484d093bea17610480efd0e88301f72a.zip cpython-3cf96ac2484d093bea17610480efd0e88301f72a.tar.gz cpython-3cf96ac2484d093bea17610480efd0e88301f72a.tar.bz2 |
Issue #17073: Fix some integer overflows in sqlite3 module.
Diffstat (limited to 'Modules/_sqlite/util.c')
-rw-r--r-- | Modules/_sqlite/util.c | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/Modules/_sqlite/util.c b/Modules/_sqlite/util.c index b7faae8..a1a462c 100644 --- a/Modules/_sqlite/util.c +++ b/Modules/_sqlite/util.c @@ -104,3 +104,69 @@ int _pysqlite_seterror(sqlite3* db, sqlite3_stmt* st) 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 PyLong_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; +} |