From 589307b04ccd590dd8e95a5ed81f95b078198edb Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Mon, 4 Jan 2021 12:37:33 +0800 Subject: [PATCH 1/3] Allocate the _curses._C_API on the heap memory. --- Modules/_cursesmodule.c | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 23f6d96f5144e2..8bf4b4c0fcfec9 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -4705,22 +4705,22 @@ static struct PyModuleDef _cursesmodule = { NULL }; +static void +curses_destructor(PyObject *op) +{ + void *ptr = PyCapsule_GetPointer(op, PyCurses_CAPSULE_NAME); + 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) @@ -4732,9 +4732,28 @@ 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 *)&PyCursesWindow_Type; // borrowed ref + 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) { + 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 */ From 05785e15fff2b8113228d5353fdc913db8b4a8dc Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Fri, 22 Jan 2021 00:07:07 +0800 Subject: [PATCH 2/3] apply victor's comment --- Modules/_cursesmodule.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index 8bf4b4c0fcfec9..ba714805ec010d 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -4709,6 +4709,7 @@ static void curses_destructor(PyObject *op) { void *ptr = PyCapsule_GetPointer(op, PyCurses_CAPSULE_NAME); + Py_DECREF(*(void **)ptr); PyMem_Free(ptr); } @@ -4738,7 +4739,7 @@ PyInit__curses(void) return NULL; } /* Initialize the C API pointer array */ - PyCurses_API[0] = (void *)&PyCursesWindow_Type; // borrowed ref + 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; From f7af44623543b1224a89c46280219fe35ac736b8 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Fri, 22 Jan 2021 09:32:16 +0800 Subject: [PATCH 3/3] apply victor's comment --- Modules/_cursesmodule.c | 1 + 1 file changed, 1 insertion(+) diff --git a/Modules/_cursesmodule.c b/Modules/_cursesmodule.c index ba714805ec010d..eaf2f95f60d44f 100644 --- a/Modules/_cursesmodule.c +++ b/Modules/_cursesmodule.c @@ -4748,6 +4748,7 @@ PyInit__curses(void) 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; }