diff --git a/Misc/NEWS.d/next/Core and Builtins/2022-02-10-02-29-12.bpo-46323.HK_cs0.rst b/Misc/NEWS.d/next/Core and Builtins/2022-02-10-02-29-12.bpo-46323.HK_cs0.rst new file mode 100644 index 00000000000..16db7c5eaea --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2022-02-10-02-29-12.bpo-46323.HK_cs0.rst @@ -0,0 +1,3 @@ +:mod:`ctypes` now allocates memory on the stack instead of on the heap +to pass arguments while calling a Python callback function. +Patch by Dong-hee Na. diff --git a/Modules/_ctypes/callbacks.c b/Modules/_ctypes/callbacks.c index f2d9a530e6e..591b944d76f 100644 --- a/Modules/_ctypes/callbacks.c +++ b/Modules/_ctypes/callbacks.c @@ -14,9 +14,18 @@ #include +#ifdef MS_WIN32 +# include +#endif + #include #include "ctypes.h" +#ifdef HAVE_ALLOCA_H +/* AIX needs alloca.h for alloca() */ +#include +#endif + /**************************************************************/ static void @@ -148,7 +157,6 @@ static void _CallPythonObject(void *mem, void **pArgs) { PyObject *result = NULL; - PyObject **args = NULL; Py_ssize_t i = 0, j = 0, nargs = 0; PyObject *error_object = NULL; int *space; @@ -156,24 +164,10 @@ static void _CallPythonObject(void *mem, assert(PyTuple_Check(converters)); nargs = PyTuple_GET_SIZE(converters); - /* Hm. What to return in case of error? - For COM, 0xFFFFFFFF seems better than 0. - */ - if (nargs < 0) { - PrintError("BUG: PySequence_Length"); - goto Done; - } - - PyObject *args_stack[CTYPES_MAX_ARGCOUNT]; - if (nargs <= CTYPES_MAX_ARGCOUNT) { - args = args_stack; - } - else { - args = PyMem_Malloc(nargs * sizeof(PyObject *)); - if (args == NULL) { - PyErr_NoMemory(); - goto Done; - } + assert(nargs <= CTYPES_MAX_ARGCOUNT); + PyObject **args = NULL; + if (nargs > 0) { + args = alloca(nargs * sizeof(PyObject *)); } PyObject **cnvs = PySequence_Fast_ITEMS(converters); @@ -310,9 +304,6 @@ static void _CallPythonObject(void *mem, for (j = 0; j < i; j++) { Py_DECREF(args[j]); } - if (args != args_stack) { - PyMem_Free(args); - } PyGILState_Release(state); } diff --git a/Modules/_ctypes/callproc.c b/Modules/_ctypes/callproc.c index 6dba0ffaa51..4a6b8ec3ee0 100644 --- a/Modules/_ctypes/callproc.c +++ b/Modules/_ctypes/callproc.c @@ -1162,11 +1162,7 @@ PyObject *_ctypes_callproc(PPROC pProc, return NULL; } - args = (struct argument *)alloca(sizeof(struct argument) * argcount); - if (!args) { - PyErr_NoMemory(); - return NULL; - } + args = alloca(sizeof(struct argument) * argcount); memset(args, 0, sizeof(struct argument) * argcount); argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes) : 0; #ifdef MS_WIN32