bpo-41798: Allocate the _curses._C_API on the heap memory (GH-24186)
diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c
index 7ab68c7..4fcedc5 100644
--- a/Modules/_cursesmodule.c
+++ b/Modules/_cursesmodule.c
@@ -4725,22 +4725,23 @@ static struct PyModuleDef _cursesmodule = {
NULL
};
+static void
+curses_destructor(PyObject *op)
+{
+ void *ptr = PyCapsule_GetPointer(op, PyCurses_CAPSULE_NAME);
+ Py_DECREF(*(void **)ptr);
+ PyMem_Free(ptr);
+}
+
PyMODINIT_FUNC
PyInit__curses(void)
{
PyObject *m, *d, *v, *c_api_object;
- static void *PyCurses_API[PyCurses_API_pointers];
/* Initialize object type */
if (PyType_Ready(&PyCursesWindow_Type) < 0)
return NULL;
- /* Initialize the C API pointer array */
- PyCurses_API[0] = (void *)&PyCursesWindow_Type;
- PyCurses_API[1] = (void *)func_PyCursesSetupTermCalled;
- PyCurses_API[2] = (void *)func_PyCursesInitialised;
- PyCurses_API[3] = (void *)func_PyCursesInitialisedColor;
-
/* Create the module and add the functions */
m = PyModule_Create(&_cursesmodule);
if (m == NULL)
@@ -4752,9 +4753,29 @@ PyInit__curses(void)
return NULL;
ModDict = d; /* For PyCurses_InitScr to use later */
+ void **PyCurses_API = PyMem_Calloc(PyCurses_API_pointers, sizeof(void *));
+ if (PyCurses_API == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ /* Initialize the C API pointer array */
+ PyCurses_API[0] = (void *)Py_NewRef(&PyCursesWindow_Type);
+ PyCurses_API[1] = (void *)func_PyCursesSetupTermCalled;
+ PyCurses_API[2] = (void *)func_PyCursesInitialised;
+ PyCurses_API[3] = (void *)func_PyCursesInitialisedColor;
+
/* Add a capsule for the C API */
- c_api_object = PyCapsule_New(PyCurses_API, PyCurses_CAPSULE_NAME, NULL);
- PyDict_SetItemString(d, "_C_API", c_api_object);
+ c_api_object = PyCapsule_New(PyCurses_API, PyCurses_CAPSULE_NAME,
+ curses_destructor);
+ if (c_api_object == NULL) {
+ Py_DECREF(PyCurses_API[0]);
+ PyMem_Free(PyCurses_API);
+ return NULL;
+ }
+ if (PyDict_SetItemString(d, "_C_API", c_api_object) < 0) {
+ Py_DECREF(c_api_object);
+ return NULL;
+ }
Py_DECREF(c_api_object);
/* For exception curses.error */