]> granicus.if.org Git - python/commitdiff
Fix bug #1518190: accept any integer or long value in the
authorThomas Heller <theller@ctypes.org>
Mon, 10 Jul 2006 09:10:28 +0000 (09:10 +0000)
committerThomas Heller <theller@ctypes.org>
Mon, 10 Jul 2006 09:10:28 +0000 (09:10 +0000)
ctypes.c_void_p constructor.

Lib/ctypes/test/test_pointers.py
Misc/NEWS
Modules/_ctypes/cfield.c

index a7a28024e34c2a816f94c25afba1250afddf3856..586655af7df13f5a57ca69d863bd068d6a64e7c6 100644 (file)
@@ -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()
index 6f28dbc0677b9614a33c78d9d8b3ad3f68b4ee87..1a976a166c146190f6c6ac91f1cf38803ad21c78 100644 (file)
--- 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.
index c5895f095e8df7e653366887116c95726c0fedd4..b147ae2ed94e20403e3f53026a8d007be31d7099 100644 (file)
@@ -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);
 }