From 11c58c4c8d8376565dbb8f04d08d915022ba5028 Mon Sep 17 00:00:00 2001 From: Thomas Heller Date: Fri, 8 Jun 2007 19:39:31 +0000 Subject: [PATCH] Merged revisions 55129-55131 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk/Lib/ctypes ........ r55129 | thomas.heller | 2007-05-04 21:54:22 +0200 (Fr, 04 Mai 2007) | 3 lines Do not truncate 64-bit pointers to 32-bit integers. Fixes SF #1703286, will backport to release25-maint. ........ r55131 | thomas.heller | 2007-05-04 21:56:32 +0200 (Fr, 04 Mai 2007) | 1 line Oops, these tests do not run on Windows CE. ........ --- Lib/ctypes/test/test_loading.py | 28 ++++++++++++++++++++++++++++ Misc/NEWS | 2 ++ Modules/_ctypes/callproc.c | 22 +++++++++++----------- Modules/_ctypes/ctypes.h | 6 ++++++ 4 files changed, 47 insertions(+), 11 deletions(-) diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py index 1e7870b79f..18dcdbfc7d 100644 --- a/Lib/ctypes/test/test_loading.py +++ b/Lib/ctypes/test/test_loading.py @@ -74,5 +74,33 @@ class LoaderTest(unittest.TestCase): self.failUnlessRaises(AttributeError, dll.__getitem__, 1234) + if os.name == "nt": + def test_1703286_A(self): + from _ctypes import LoadLibrary, FreeLibrary + # On winXP 64-bit, advapi32 loads at an address that does + # NOT fit into a 32-bit integer. FreeLibrary must be able + # to accept this address. + + # These are tests for http://www.python.org/sf/1703286 + handle = LoadLibrary("advapi32") + FreeLibrary(handle) + + def test_1703286_B(self): + # Since on winXP 64-bit advapi32 loads like described + # above, the (arbitrarily selected) CloseEventLog function + # also has a high address. 'call_function' should accept + # addresses so large. + from _ctypes import call_function + advapi32 = windll.advapi32 + # Calling CloseEventLog with a NULL argument should fail, + # but the call should not segfault or so. + self.failUnlessEqual(0, advapi32.CloseEventLog(None)) + windll.kernel32.GetProcAddress.argtypes = c_void_p, c_char_p + windll.kernel32.GetProcAddress.restype = c_void_p + proc = windll.kernel32.GetProcAddress(advapi32._handle, "CloseEventLog") + self.failUnless(proc) + # This is the real test: call the function via 'call_function' + self.failUnlessEqual(0, call_function(proc, (None,))) + if __name__ == "__main__": unittest.main() diff --git a/Misc/NEWS b/Misc/NEWS index 136ab5c3da..4f9d648750 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -54,6 +54,8 @@ Library Extension Modules ----------------- +- Bug #1703286: ctypes no longer truncates 64-bit pointers. + - Bug #1721309: prevent bsddb module from freeing random memory. - Bug #1726026: Correct the field names of WIN32_FIND_DATAA and diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 0c35f38386..58aa9bb623 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1111,10 +1111,10 @@ static char free_library_doc[] = Free the handle of an executable previously loaded by LoadLibrary.\n"; static PyObject *free_library(PyObject *self, PyObject *args) { - HMODULE hMod; - if (!PyArg_ParseTuple(args, "i:FreeLibrary", &hMod)) + void *hMod; + if (!PyArg_ParseTuple(args, PY_VOID_P_CODE ":FreeLibrary", &hMod)) return NULL; - if (!FreeLibrary(hMod)) + if (!FreeLibrary((HMODULE)hMod)) return PyErr_SetFromWindowsErr(GetLastError()); Py_INCREF(Py_None); return Py_None; @@ -1233,9 +1233,9 @@ static PyObject *py_dl_open(PyObject *self, PyObject *args) static PyObject *py_dl_close(PyObject *self, PyObject *args) { - void * handle; + void *handle; - if (!PyArg_ParseTuple(args, "i:dlclose", &handle)) + if (!PyArg_ParseTuple(args, PY_VOID_P_CODE ":dlclose", &handle)) return NULL; if (dlclose(handle)) { PyErr_SetString(PyExc_OSError, @@ -1252,7 +1252,7 @@ static PyObject *py_dl_sym(PyObject *self, PyObject *args) void *handle; void *ptr; - if (!PyArg_ParseTuple(args, "is:dlsym", &handle, &name)) + if (!PyArg_ParseTuple(args, PY_VOID_P_CODE "s:dlsym", &handle, &name)) return NULL; ptr = ctypes_dlsym(handle, name); if (!ptr) { @@ -1260,7 +1260,7 @@ static PyObject *py_dl_sym(PyObject *self, PyObject *args) ctypes_dlerror()); return NULL; } - return Py_BuildValue("i", ptr); + return PyLong_FromVoidPtr(ptr); } #endif @@ -1272,12 +1272,12 @@ static PyObject *py_dl_sym(PyObject *self, PyObject *args) static PyObject * call_function(PyObject *self, PyObject *args) { - PPROC func; + void *func; PyObject *arguments; PyObject *result; if (!PyArg_ParseTuple(args, - "iO!", + PY_VOID_P_CODE "O!", &func, &PyTuple_Type, &arguments)) return NULL; @@ -1303,12 +1303,12 @@ call_function(PyObject *self, PyObject *args) static PyObject * call_cdeclfunction(PyObject *self, PyObject *args) { - PPROC func; + void *func; PyObject *arguments; PyObject *result; if (!PyArg_ParseTuple(args, - "iO!", + PY_VOID_P_CODE "O!", &func, &PyTuple_Type, &arguments)) return NULL; diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 0af7851020..5fb603075d 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -23,6 +23,12 @@ typedef int Py_ssize_t; #define PY_LONG_LONG LONG_LONG #endif +#if SIZEOF_VOID_P == SIZEOF_LONG +#define PY_VOID_P_CODE "k" +#elif defined(HAVE_LONG_LONG) && (SIZEOF_VOID_P == SIZEOF_LONG_LONG) +#define PY_VOID_P_CODE "K" +#endif + typedef struct tagPyCArgObject PyCArgObject; typedef struct tagCDataObject CDataObject; typedef PyObject *(* GETFUNC)(void *, unsigned size); -- 2.50.1