summaryrefslogtreecommitdiffstats
path: root/Modules/_sqlite/util.c
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2013-02-07 15:03:46 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2013-02-07 15:03:46 (GMT)
commit2efdc90b0f49866d857a5b3dc21b7c791f7a0aeb (patch)
tree5a929d957c94083e8ab89ca35cf05d7f00cc19e3 /Modules/_sqlite/util.c
parent03ee12ed7251b6b251d55d708a22616ed2538b19 (diff)
parent3cf96ac2484d093bea17610480efd0e88301f72a (diff)
downloadcpython-2efdc90b0f49866d857a5b3dc21b7c791f7a0aeb.zip
cpython-2efdc90b0f49866d857a5b3dc21b7c791f7a0aeb.tar.gz
cpython-2efdc90b0f49866d857a5b3dc21b7c791f7a0aeb.tar.bz2
Issue #17073: Fix some integer overflows in sqlite3 module.
Diffstat (limited to 'Modules/_sqlite/util.c')
-rw-r--r--Modules/_sqlite/util.c66
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;
+}