Skip to content

Commit

Permalink
bpo-41798: Allocate the _curses._C_API on the heap memory (GH-24186)
Browse files Browse the repository at this point in the history
  • Loading branch information
shihai1991 authored Jan 22, 2021
1 parent 644d528 commit 2f12a1b
Showing 1 changed file with 30 additions and 9 deletions.
39 changes: 30 additions & 9 deletions Modules/_cursesmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 */
Expand Down

0 comments on commit 2f12a1b

Please sign in to comment.