From 91142c00a45b78d6dafd9e0a472243cff951a507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Sabl=C3=A9?= Date: Fri, 1 Mar 2013 11:37:20 +0100 Subject: Fix handling of unsigned long long and provide unittests. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I29674a2d758ebf4650e2fe26cdc2e663c0bae5c7 Reviewed-by: Sébastien Sablé Reviewed-by: Hugo Parente Lima --- libshiboken/conversions.h | 14 +++++++++++++- libshiboken/sbkconverter_p.h | 12 +++++++++++- tests/libsample/functions.cpp | 12 ++++++++++++ tests/libsample/functions.h | 2 ++ tests/samplebinding/overflow_test.py | 18 ++++++++++++++++++ tests/samplebinding/typesystem_sample.xml | 4 ++++ 6 files changed, 60 insertions(+), 2 deletions(-) diff --git a/libshiboken/conversions.h b/libshiboken/conversions.h index b925770..6a0429e 100644 --- a/libshiboken/conversions.h +++ b/libshiboken/conversions.h @@ -435,7 +435,19 @@ struct Converter } static inline unsigned PY_LONG_LONG toCpp(PyObject* pyobj) { - return (unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLong(pyobj); + if (PyInt_Check(pyobj)) { + long result = (unsigned PY_LONG_LONG) PyInt_AsLong(pyobj); + if (result < 0) { + PyErr_SetObject(PyExc_OverflowError, 0); + return 0; + } else + return (unsigned PY_LONG_LONG) result; + } else if (PyLong_Check(pyobj)) { + return (unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLong(pyobj); + } else { + PyErr_SetString(PyExc_TypeError, "Invalid type for unsigned long long conversion"); + return 0; + } } }; diff --git a/libshiboken/sbkconverter_p.h b/libshiboken/sbkconverter_p.h index b1d40ee..766e6fa 100644 --- a/libshiboken/sbkconverter_p.h +++ b/libshiboken/sbkconverter_p.h @@ -251,7 +251,17 @@ struct Primitive : OnePrimitive } static void toCpp(PyObject* pyIn, void* cppOut) { - *((unsigned PY_LONG_LONG*)cppOut) = (unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLong(pyIn); + if (PyInt_Check(pyIn)) { + long result = (unsigned PY_LONG_LONG) PyInt_AsLong(pyIn); + if (result < 0) + PyErr_SetObject(PyExc_OverflowError, 0); + else + *((unsigned PY_LONG_LONG*)cppOut) = (unsigned PY_LONG_LONG) result; + } else if (PyLong_Check(pyIn)) { + *((unsigned PY_LONG_LONG*)cppOut) = (unsigned PY_LONG_LONG) PyLong_AsUnsignedLongLong(pyIn); + } else { + PyErr_SetString(PyExc_TypeError, "Invalid type for unsigned long long conversion"); + } } static PythonToCppFunc isConvertible(PyObject* pyIn) { diff --git a/tests/libsample/functions.cpp b/tests/libsample/functions.cpp index 9a0bf2e..be1e2f9 100644 --- a/tests/libsample/functions.cpp +++ b/tests/libsample/functions.cpp @@ -131,6 +131,18 @@ doubleUnsignedInt(unsigned int value) return value * 2; } +long long +doubleLongLong(long long value) +{ + return value * 2; +} + +unsigned long long +doubleUnsignedLongLong(unsigned long long value) +{ + return value * 2; +} + short doubleShort(short value) { diff --git a/tests/libsample/functions.h b/tests/libsample/functions.h index 848777e..95adb2d 100644 --- a/tests/libsample/functions.h +++ b/tests/libsample/functions.h @@ -62,6 +62,8 @@ LIBSAMPLE_API GlobalOverloadFuncEnum overloadedFunc(int val); LIBSAMPLE_API GlobalOverloadFuncEnum overloadedFunc(double val); LIBSAMPLE_API unsigned int doubleUnsignedInt(unsigned int value); +LIBSAMPLE_API long long doubleLongLong(long long value); +LIBSAMPLE_API unsigned long long doubleUnsignedLongLong(unsigned long long value); LIBSAMPLE_API short doubleShort(short value); LIBSAMPLE_API int acceptInt(int x); diff --git a/tests/samplebinding/overflow_test.py b/tests/samplebinding/overflow_test.py index 4529fe2..ea2dd37 100644 --- a/tests/samplebinding/overflow_test.py +++ b/tests/samplebinding/overflow_test.py @@ -41,6 +41,24 @@ class OverflowTest(unittest.TestCase): val *= -1 self.assertRaises(OverflowError, doubleUnsignedInt, val) + def testLongLong(self): + '''C++ function receives an long long argument and raise OverflowError if the value is negative.''' + val = 100 + self.assertEqual(doubleLongLong(val), 2 * val) + val = long(100) + self.assertEqual(doubleLongLong(val), 2 * val) + val = (2 << 64) + 1 + self.assertRaises(OverflowError, doubleLongLong, val) + + def testUnsignedLongLong(self): + '''C++ function receives an unsigned long long argument and raise OverflowError if the value is negative.''' + val = 100 + self.assertEqual(doubleUnsignedLongLong(val), 2 * val) + val = long(100) + self.assertEqual(doubleUnsignedLongLong(val), 2 * val) + val *= -1 + self.assertRaises(OverflowError, doubleUnsignedLongLong, val) + def testOverflow(self): '''Calls function with unsigned int parameter using an overflowing value.''' self.assertRaises(OverflowError, doubleUnsignedInt, 42415335332353253) diff --git a/tests/samplebinding/typesystem_sample.xml b/tests/samplebinding/typesystem_sample.xml index 6379dba..0a9a764 100644 --- a/tests/samplebinding/typesystem_sample.xml +++ b/tests/samplebinding/typesystem_sample.xml @@ -22,6 +22,8 @@ + + @@ -481,6 +483,8 @@ + + -- cgit v1.2.3