summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Lib/ctypes/test/test_loading.py27
-rw-r--r--Modules/_ctypes/callproc.c26
-rw-r--r--Modules/_ctypes/ctypes.h6
3 files changed, 46 insertions, 13 deletions
diff --git a/Lib/ctypes/test/test_loading.py b/Lib/ctypes/test/test_loading.py
index 28c83fd4a9..ee34754d94 100644
--- a/Lib/ctypes/test/test_loading.py
+++ b/Lib/ctypes/test/test_loading.py
@@ -58,6 +58,33 @@ class LoaderTest(unittest.TestCase):
windll.LoadLibrary("coredll").GetModuleHandleW
WinDLL("coredll").GetModuleHandleW
+ 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,)))
+
def test_load_ordinal_functions(self):
import _ctypes_test
dll = WinDLL(_ctypes_test.__file__)
diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c
index b7dda48a86..a8d4ce1601 100644
--- a/Modules/_ctypes/callproc.c
+++ b/Modules/_ctypes/callproc.c
@@ -1128,10 +1128,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;
@@ -1250,11 +1250,11 @@ static PyObject *py_dl_open(PyObject *self, PyObject *args)
static PyObject *py_dl_close(PyObject *self, PyObject *args)
{
- int handle;
+ void *handle;
- if (!PyArg_ParseTuple(args, "i:dlclose", &handle))
+ if (!PyArg_ParseTuple(args, PY_VOID_P_CODE ":dlclose", &handle))
return NULL;
- if (dlclose((void*)handle)) {
+ if (dlclose(handle)) {
PyErr_SetString(PyExc_OSError,
ctypes_dlerror());
return NULL;
@@ -1266,10 +1266,10 @@ static PyObject *py_dl_close(PyObject *self, PyObject *args)
static PyObject *py_dl_sym(PyObject *self, PyObject *args)
{
char *name;
- int handle;
+ 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((void*)handle, name);
if (!ptr) {
@@ -1277,7 +1277,7 @@ static PyObject *py_dl_sym(PyObject *self, PyObject *args)
ctypes_dlerror());
return NULL;
}
- return Py_BuildValue("i", ptr);
+ return PyLong_FromVoidPtr(ptr);
}
#endif
@@ -1289,12 +1289,12 @@ static PyObject *py_dl_sym(PyObject *self, PyObject *args)
static PyObject *
call_function(PyObject *self, PyObject *args)
{
- int func;
+ void *func;
PyObject *arguments;
PyObject *result;
if (!PyArg_ParseTuple(args,
- "iO!",
+ PY_VOID_P_CODE "O!",
&func,
&PyTuple_Type, &arguments))
return NULL;
@@ -1320,12 +1320,12 @@ call_function(PyObject *self, PyObject *args)
static PyObject *
call_cdeclfunction(PyObject *self, PyObject *args)
{
- int 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);