From: Thomas Heller Date: Mon, 10 Jul 2006 09:10:28 +0000 (+0000) Subject: Fix bug #1518190: accept any integer or long value in the X-Git-Tag: v2.5b2~11 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=dda068dee1937d0dd144568a83e2a47e5c26f9a2;p=python Fix bug #1518190: accept any integer or long value in the ctypes.c_void_p constructor. --- diff --git a/Lib/ctypes/test/test_pointers.py b/Lib/ctypes/test/test_pointers.py index a7a28024e3..586655af7d 100644 --- a/Lib/ctypes/test/test_pointers.py +++ b/Lib/ctypes/test/test_pointers.py @@ -157,6 +157,23 @@ class PointersTestCase(unittest.TestCase): q = pointer(y) pp[0] = q # <== self.failUnlessEqual(p[0], 6) + def test_c_void_p(self): + # http://sourceforge.net/tracker/?func=detail&aid=1518190&group_id=5470&atid=105470 + if sizeof(c_void_p) == 4: + self.failUnlessEqual(c_void_p(0xFFFFFFFFL).value, + c_void_p(-1).value) + self.failUnlessEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value, + c_void_p(-1).value) + elif sizeof(c_void_p) == 8: + self.failUnlessEqual(c_void_p(0xFFFFFFFFL).value, + 0xFFFFFFFFL) + self.failUnlessEqual(c_void_p(0xFFFFFFFFFFFFFFFFL).value, + c_void_p(-1).value) + self.failUnlessEqual(c_void_p(0xFFFFFFFFFFFFFFFFFFFFFFFFL).value, + c_void_p(-1).value) + + self.assertRaises(TypeError, c_void_p, 3.14) # make sure floats are NOT accepted + self.assertRaises(TypeError, c_void_p, object()) # nor other objects if __name__ == '__main__': unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS index 6f28dbc067..1a976a166c 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -39,6 +39,9 @@ Core and builtins Library ------- +- Bug #1518190: The ctypes.c_void_p constructor now accepts any + integer or long, without range checking. + - Bug #1508010: msvccompiler now requires the DISTUTILS_USE_SDK environment variable to be set in order to the SDK environment for finding the compiler, include files, etc. diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index c5895f095e..b147ae2ed9 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -1486,16 +1486,27 @@ P_set(void *ptr, PyObject *value, unsigned size) *(void **)ptr = NULL; _RET(value); } - - v = PyLong_AsVoidPtr(value); - if (PyErr_Occurred()) { - /* prevent the SystemError: bad argument to internal function */ - if (!PyInt_Check(value) && !PyLong_Check(value)) { - PyErr_SetString(PyExc_TypeError, - "cannot be converted to pointer"); - } + + if (!PyInt_Check(value) && !PyLong_Check(value)) { + PyErr_SetString(PyExc_TypeError, + "cannot be converted to pointer"); return NULL; } + +#if SIZEOF_VOID_P <= SIZEOF_LONG + v = (void *)PyInt_AsUnsignedLongMask(value); +#else +#ifndef HAVE_LONG_LONG +# error "PyLong_AsVoidPtr: sizeof(void*) > sizeof(long), but no long long" +#elif SIZEOF_LONG_LONG < SIZEOF_VOID_P +# error "PyLong_AsVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)" +#endif + v = (void *)PyInt_AsUnsignedLongLongMask(value); +#endif + + if (PyErr_Occurred()) + return NULL; + *(void **)ptr = v; _RET(value); }