@@ -207,34 +207,49 @@ static char *CURSES_SCREEN_ENCODING = NULL;
207207#define PyCursesInitialisedColor \
208208 CHECK_STATE_FLAG("start_color", CURSES_INITIALISED_COLORS)
209209
210- #define CHECK_NOT_NULL_OR_ERROR (VALUE ) \
211- do { \
212- if ((VALUE) == NULL) { \
213- goto error; \
214- } \
215- } while (0)
216-
217- #define CHECK_RET_CODE_OR_ERROR (STATUS ) \
210+ /* Jump to the 'error' label if STATUS < 0. */
211+ #define CHECK_RET_CODE (STATUS ) \
218212 do { \
219213 if ((STATUS) < 0) { \
214+ assert(PyErr_Occurred()); \
220215 goto error; \
221216 } \
222217 } while (0)
223218
224- #define CHECK_RET_FLAG_OR_ERROR (STATUS ) \
225- do { \
226- if (!(STATUS)) { \
227- goto error; \
228- } \
219+ /*
220+ * Equivalent to DICT[NAME] = VALUE; on error, jump to the 'error' label.
221+ *
222+ * Parameters
223+ *
224+ * PyObject * DICT The Python dict to alter.
225+ * const char * NAME The constant name.
226+ * long VALUE The constant value.
227+ */
228+ #define DICT_ADD_INT_VALUE (DICT , NAME , VALUE ) \
229+ do { \
230+ PyObject *value = PyLong_FromLong((long)(VALUE)); \
231+ if (value == NULL) { \
232+ goto error; \
233+ } \
234+ int rc = PyDict_SetItemString((DICT), (NAME), value); \
235+ Py_DECREF(value); \
236+ CHECK_RET_CODE(rc); \
229237 } while (0)
230238
231- #define DICT_ADD_INT_VALUE_OR_ERROR (DICT_OBJECT , STRING , VALUE ) \
232- do { \
233- PyObject *value = PyLong_FromLong((long)(VALUE)); \
234- CHECK_NOT_NULL_OR_ERROR(value); \
235- int rc = PyDict_SetItemString((DICT_OBJECT), (STRING), value); \
236- Py_DECREF(value); \
237- CHECK_RET_CODE_OR_ERROR(rc); \
239+ /*
240+ * Add an integral constant to a module; on error, jump to the 'error' label.
241+ *
242+ * Parameters
243+ *
244+ * PyObject * MODULE The module object to alter.
245+ * const char * NAME The constant name.
246+ * long VALUE The constant value.
247+ */
248+ #define MODULE_ADD_INT_CONSTANT (MODULE , NAME , VALUE ) \
249+ do { \
250+ long value = (long)(VALUE); \
251+ int rc = PyModule_AddIntConstant((MODULE), (NAME), value); \
252+ CHECK_RET_CODE(rc); \
238253 } while (0)
239254
240255/* Utility Functions */
@@ -754,13 +769,13 @@ PyCursesWindow_New(WINDOW *win, const char *encoding)
754769static void
755770PyCursesWindow_Dealloc (PyCursesWindowObject * wo )
756771{
757- if (wo -> win != stdscr && wo -> win != NULL ) {
758- delwin (wo -> win );
759- wo -> win = NULL ;
772+ if (wo -> win != stdscr ) {
773+ // Silently ignore errors in delwin(3) (e.g., passing
774+ // a NULL pointer results in delwin() returning ERR).
775+ (void )delwin (wo -> win );
760776 }
761777 if (wo -> encoding != NULL ) {
762778 PyMem_Free (wo -> encoding );
763- wo -> encoding = NULL ;
764779 }
765780 PyObject_Free (wo );
766781}
@@ -3325,9 +3340,10 @@ _curses_initscr_impl(PyObject *module)
33253340
33263341 /* Here are some graphic symbols you can use */
33273342 PyObject * module_dict = PyModule_GetDict (module );
3328- CHECK_NOT_NULL_OR_ERROR (module_dict );
3329- #define SetDictInt (NAME , VALUE ) \
3330- DICT_ADD_INT_VALUE_OR_ERROR(module_dict, (NAME), (VALUE))
3343+ if (module_dict == NULL ) {
3344+ goto error ;
3345+ }
3346+ #define SetDictInt (NAME , VALUE ) DICT_ADD_INT_VALUE(module_dict, (NAME), (VALUE))
33313347
33323348 SetDictInt ("ACS_ULCORNER" , (ACS_ULCORNER ));
33333349 SetDictInt ("ACS_LLCORNER" , (ACS_LLCORNER ));
@@ -3400,7 +3416,9 @@ _curses_initscr_impl(PyObject *module)
34003416#undef SetDictInt
34013417
34023418 PyCursesWindowObject * winobj = (PyCursesWindowObject * )PyCursesWindow_New (win , NULL );
3403- CHECK_NOT_NULL_OR_ERROR (winobj );
3419+ if (winobj == NULL ) {
3420+ goto error ;
3421+ }
34043422 CURSES_SCREEN_ENCODING = winobj -> encoding ;
34053423 return (PyObject * )winobj ;
34063424
@@ -4008,27 +4026,21 @@ _curses_qiflush_impl(PyObject *module, int flag)
40084026/* Internal helper used for updating curses.LINES, curses.COLS, _curses.LINES
40094027 * and _curses.COLS */
40104028#if defined(HAVE_CURSES_RESIZETERM ) || defined(HAVE_CURSES_RESIZE_TERM )
4011- static int
4029+ static int /* 1 on success, 0 on failure */
40124030update_lines_cols (PyObject * private_module )
40134031{
4014- PyObject * exposed_module = NULL , * o = NULL ;
4015- exposed_module = PyImport_ImportModule ("curses" );
4016- CHECK_NOT_NULL_OR_ERROR (exposed_module );
4017- o = PyLong_FromLong (LINES );
4018- CHECK_NOT_NULL_OR_ERROR (o );
4019- CHECK_RET_CODE_OR_ERROR (PyObject_SetAttrString (exposed_module , "LINES" , o ));
4020- CHECK_RET_CODE_OR_ERROR (PyObject_SetAttrString (private_module , "LINES" , o ));
4021- Py_DECREF (o );
4022- o = PyLong_FromLong (COLS );
4023- CHECK_NOT_NULL_OR_ERROR (o );
4024- CHECK_RET_CODE_OR_ERROR (PyObject_SetAttrString (exposed_module , "COLS" , o ));
4025- CHECK_RET_CODE_OR_ERROR (PyObject_SetAttrString (private_module , "COLS" , o ));
4026- Py_DECREF (o );
4032+ PyObject * exposed_module = PyImport_ImportModule ("curses" );
4033+ if (exposed_module == NULL ) {
4034+ return 0 ;
4035+ }
4036+ MODULE_ADD_INT_CONSTANT (exposed_module , "LINES" , LINES );
4037+ MODULE_ADD_INT_CONSTANT (private_module , "LINES" , LINES );
4038+ MODULE_ADD_INT_CONSTANT (exposed_module , "COLS" , COLS );
4039+ MODULE_ADD_INT_CONSTANT (private_module , "COLS" , COLS );
40274040 Py_DECREF (exposed_module );
40284041 return 1 ;
40294042
40304043error :
4031- Py_XDECREF (o );
40324044 Py_XDECREF (exposed_module );
40334045 return 0 ;
40344046}
@@ -4122,16 +4134,18 @@ static PyObject *
41224134_curses_resizeterm_impl (PyObject * module , int nlines , int ncols )
41234135/*[clinic end generated code: output=56d6bcc5194ad055 input=0fca02ebad5ffa82]*/
41244136{
4137+ PyObject * result ;
4138+
41254139 PyCursesInitialised ;
41264140
4127- PyObject * result = PyCursesCheckERR (resizeterm (nlines , ncols ), "resizeterm" );
4128- CHECK_NOT_NULL_OR_ERROR (result );
4129- CHECK_RET_FLAG_OR_ERROR (update_lines_cols (module ));
4141+ result = PyCursesCheckERR (resizeterm (nlines , ncols ), "resizeterm" );
4142+ if (!result )
4143+ return NULL ;
4144+ if (!update_lines_cols (module )) {
4145+ Py_DECREF (result );
4146+ return NULL ;
4147+ }
41304148 return result ;
4131-
4132- error :
4133- Py_XDECREF (result );
4134- return NULL ;
41354149}
41364150
41374151#endif
@@ -4159,16 +4173,18 @@ static PyObject *
41594173_curses_resize_term_impl (PyObject * module , int nlines , int ncols )
41604174/*[clinic end generated code: output=9e26d8b9ea311ed2 input=2197edd05b049ed4]*/
41614175{
4176+ PyObject * result ;
4177+
41624178 PyCursesInitialised ;
41634179
4164- PyObject * result = PyCursesCheckERR (resize_term (nlines , ncols ), "resize_term" );
4165- CHECK_NOT_NULL_OR_ERROR (result );
4166- CHECK_RET_FLAG_OR_ERROR (update_lines_cols (module ));
4180+ result = PyCursesCheckERR (resize_term (nlines , ncols ), "resize_term" );
4181+ if (!result )
4182+ return NULL ;
4183+ if (!update_lines_cols (module )) {
4184+ Py_DECREF (result );
4185+ return NULL ;
4186+ }
41674187 return result ;
4168-
4169- error :
4170- Py_XDECREF (result );
4171- return NULL ;
41724188}
41734189#endif /* HAVE_CURSES_RESIZE_TERM */
41744190
@@ -4232,9 +4248,11 @@ _curses_start_color_impl(PyObject *module)
42324248 if (start_color () != ERR ) {
42334249 CURSES_INITIALISED_COLORS = TRUE;
42344250 PyObject * module_dict = PyModule_GetDict (module );
4235- CHECK_NOT_NULL_OR_ERROR (module_dict );
4236- DICT_ADD_INT_VALUE_OR_ERROR (module_dict , "COLORS" , COLORS );
4237- DICT_ADD_INT_VALUE_OR_ERROR (module_dict , "COLOR_PAIRS" , COLOR_PAIRS );
4251+ if (module_dict == NULL ) {
4252+ return NULL ;
4253+ }
4254+ DICT_ADD_INT_VALUE (module_dict , "COLORS" , COLORS );
4255+ DICT_ADD_INT_VALUE (module_dict , "COLOR_PAIRS" , COLOR_PAIRS );
42384256 Py_RETURN_NONE ;
42394257 }
42404258 else {
@@ -4615,7 +4633,9 @@ make_ncurses_version(PyTypeObject *type)
46154633#define SET_VERSION_COMPONENT (INDEX , VALUE ) \
46164634 do { \
46174635 PyObject *o = PyLong_FromLong(VALUE); \
4618- CHECK_NOT_NULL_OR_ERROR(o); \
4636+ if (o == NULL) { \
4637+ goto error; \
4638+ } \
46194639 PyStructSequence_SET_ITEM(ncurses_version, INDEX, o); \
46204640 } while (0)
46214641
@@ -4764,18 +4784,22 @@ PyInit__curses(void)
47644784 PyObject * mod = NULL ;
47654785
47664786 /* Initialize object type */
4767- CHECK_RET_CODE_OR_ERROR (PyType_Ready (& PyCursesWindow_Type ));
4787+ CHECK_RET_CODE (PyType_Ready (& PyCursesWindow_Type ));
47684788
47694789 /* Create the module and add the functions */
47704790 mod = PyModule_Create (& _cursesmodule );
4771- CHECK_NOT_NULL_OR_ERROR (mod );
4791+ if (mod == NULL ) {
4792+ goto error ;
4793+ }
47724794#ifdef Py_GIL_DISABLED
47734795 CHECK_RET_CODE_OR_ERROR (PyUnstable_Module_SetGIL (mod , Py_MOD_GIL_NOT_USED ));
47744796#endif
47754797
47764798 /* Add some symbolic constants to the module */
47774799 PyObject * module_dict = PyModule_GetDict (mod );
4778- CHECK_NOT_NULL_OR_ERROR (module_dict );
4800+ if (module_dict == NULL ) {
4801+ goto error ;
4802+ }
47794803
47804804 void * * PyCurses_API = PyMem_Calloc (PyCurses_API_pointers , sizeof (void * ));
47814805 if (PyCurses_API == NULL ) {
@@ -4798,42 +4822,49 @@ PyInit__curses(void)
47984822 }
47994823 int rc = PyDict_SetItemString (module_dict , "_C_API" , c_api_object );
48004824 Py_DECREF (c_api_object );
4801- CHECK_RET_CODE_OR_ERROR (rc );
4825+ CHECK_RET_CODE (rc );
48024826
48034827 /* For exception curses.error */
48044828 PyCursesError = PyErr_NewException ("_curses.error" , NULL , NULL );
4805- CHECK_NOT_NULL_OR_ERROR (PyCursesError );
4829+ if (PyCursesError == NULL ) {
4830+ goto error ;
4831+ }
48064832 rc = PyDict_SetItemString (module_dict , "error" , PyCursesError );
48074833 Py_DECREF (PyCursesError );
4808- CHECK_RET_CODE_OR_ERROR (rc );
4834+ CHECK_RET_CODE (rc );
48094835
48104836 /* Make the version available */
48114837 PyObject * curses_version = PyBytes_FromString (PyCursesVersion );
4812- CHECK_NOT_NULL_OR_ERROR (curses_version );
4838+ if (curses_version == NULL ) {
4839+ goto error ;
4840+ }
48134841 rc = PyDict_SetItemString (module_dict , "version" , curses_version );
48144842 Py_DECREF (curses_version );
4815- CHECK_RET_CODE_OR_ERROR (rc );
4843+ CHECK_RET_CODE (rc );
48164844 Py_INCREF (curses_version );
48174845 rc = PyDict_SetItemString (module_dict , "__version__" , curses_version );
48184846 Py_CLEAR (curses_version );
4819- CHECK_RET_CODE_OR_ERROR (rc );
4847+ CHECK_RET_CODE (rc );
48204848
48214849#ifdef NCURSES_VERSION
48224850 /* ncurses_version */
48234851 PyTypeObject * version_type ;
48244852 version_type = _PyStructSequence_NewType (& ncurses_version_desc ,
48254853 Py_TPFLAGS_DISALLOW_INSTANTIATION );
4826- CHECK_NOT_NULL_OR_ERROR (version_type );
4854+ if (version_type == NULL ) {
4855+ goto error ;
4856+ }
48274857 PyObject * ncurses_version = make_ncurses_version (version_type );
48284858 Py_DECREF (version_type );
4829- CHECK_NOT_NULL_OR_ERROR (ncurses_version );
4859+ if (ncurses_version == NULL ) {
4860+ goto error ;
4861+ }
48304862 rc = PyDict_SetItemString (module_dict , "ncurses_version" , ncurses_version );
48314863 Py_CLEAR (ncurses_version );
4832- CHECK_RET_CODE_OR_ERROR (rc );
4864+ CHECK_RET_CODE (rc );
48334865#endif /* NCURSES_VERSION */
48344866
4835- #define SetDictInt (NAME , VALUE ) \
4836- DICT_ADD_INT_VALUE_OR_ERROR(module_dict, (NAME), (VALUE))
4867+ #define SetDictInt (NAME , VALUE ) DICT_ADD_INT_VALUE(module_dict, (NAME), (VALUE))
48374868
48384869 SetDictInt ("ERR" , ERR );
48394870 SetDictInt ("OK" , OK );
@@ -4952,11 +4983,13 @@ PyInit__curses(void)
49524983 }
49534984 * p2 = (char )0 ;
49544985 PyObject * p_keycode = PyLong_FromLong ((long )keycode );
4955- CHECK_NOT_NULL_OR_ERROR (p_keycode );
4986+ if (p_keycode == NULL ) {
4987+ goto error ;
4988+ }
49564989 int rc = PyDict_SetItemString (module_dict , fn_key_name , p_keycode );
49574990 Py_DECREF (p_keycode );
49584991 PyMem_Free (fn_key_name );
4959- CHECK_RET_CODE_OR_ERROR (rc );
4992+ CHECK_RET_CODE (rc );
49604993 }
49614994 else {
49624995 SetDictInt (key_name , keycode );
@@ -4966,16 +4999,16 @@ PyInit__curses(void)
49664999 SetDictInt ("KEY_MAX" , KEY_MAX );
49675000#undef SetDictInt
49685001
4969- CHECK_RET_CODE_OR_ERROR (PyModule_AddType (mod , & PyCursesWindow_Type ));
5002+ CHECK_RET_CODE (PyModule_AddType (mod , & PyCursesWindow_Type ));
49705003 return mod ;
49715004
49725005error :
49735006 Py_XDECREF (mod );
49745007 return NULL ;
49755008}
49765009
4977- #undef DICT_ADD_INT_VALUE_OR_ERROR
5010+ #undef DICT_ADD_INT_VALUE
49785011#undef CHECK_RET_FLAG_OR_ERROR
4979- #undef CHECK_RET_CODE_OR_ERROR
5012+ #undef CHECK_RET_CODE
49805013#undef CHECK_NOT_NULL_OR_ERROR
49815014#undef CHECK_STATE_FLAG
0 commit comments