From 2f12a1b7ecc9e0cf39b4c6994473e6cb9989f81b Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Fri, 22 Jan 2021 18:06:43 +0800 Subject: bpo-41798: Allocate the _curses._C_API on the heap memory (GH-24186) --- Modules/_cursesmodule.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) 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 */ -- cgit v0.12