From 19bb2f0ced355473e5617bcfbffc57181ef36d7f Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sat, 9 Mar 2024 17:45:26 +0300 Subject: [PATCH 1/2] gh-116545: Fix error handling in `mkpwent` in `pwdmodule` --- Modules/pwdmodule.c | 73 ++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 31 deletions(-) diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c index b7034369c4731ee..1997e308201fb40 100644 --- a/Modules/pwdmodule.c +++ b/Modules/pwdmodule.c @@ -64,53 +64,64 @@ static struct PyModuleDef pwdmodule; #define DEFAULT_BUFFER_SIZE 1024 -static void -sets(PyObject *v, int i, const char* val) -{ - if (val) { - PyObject *o = PyUnicode_DecodeFSDefault(val); - PyStructSequence_SET_ITEM(v, i, o); - } - else { - PyStructSequence_SET_ITEM(v, i, Py_None); - Py_INCREF(Py_None); - } -} - static PyObject * mkpwent(PyObject *module, struct passwd *p) { - int setIndex = 0; PyObject *v = PyStructSequence_New(get_pwd_state(module)->StructPwdType); - if (v == NULL) + if (v == NULL) { return NULL; + } -#define SETS(i,val) sets(v, i, val) + int setIndex = 0; - SETS(setIndex++, p->pw_name); +#define SET_STRING(VAL) \ + do { \ + const char* val = (VAL); \ + if (val) { \ + PyObject *obj = PyUnicode_DecodeFSDefault(val); \ + if (obj == NULL) { \ + goto error; \ + } \ + PyStructSequence_SET_ITEM(v, setIndex++, obj); \ + } \ + else { \ + PyStructSequence_SET_ITEM(v, setIndex++, Py_NewRef(Py_None)); \ + } \ + } while(0) + +#define SET_RESULT(CALL) \ + do { \ + PyObject *item = (CALL); \ + if (item == NULL) { \ + goto error; \ + } \ + PyStructSequence_SET_ITEM(v, setIndex++, item); \ + } while(0) + + SET_STRING(p->pw_name); #if defined(HAVE_STRUCT_PASSWD_PW_PASSWD) && !defined(__ANDROID__) - SETS(setIndex++, p->pw_passwd); + SET_STRING(p->pw_passwd); #else - SETS(setIndex++, ""); + SET_STRING(""); #endif - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromUid(p->pw_uid)); - PyStructSequence_SET_ITEM(v, setIndex++, _PyLong_FromGid(p->pw_gid)); + SET_RESULT(_PyLong_FromUid(p->pw_uid)); + SET_RESULT(_PyLong_FromGid(p->pw_gid)); #if defined(HAVE_STRUCT_PASSWD_PW_GECOS) - SETS(setIndex++, p->pw_gecos); + SET_STRING(p->pw_gecos); #else - SETS(setIndex++, ""); + SET_STRING(""); #endif - SETS(setIndex++, p->pw_dir); - SETS(setIndex++, p->pw_shell); + SET_STRING(p->pw_dir); + SET_STRING(p->pw_shell); -#undef SETS - - if (PyErr_Occurred()) { - Py_XDECREF(v); - return NULL; - } +#undef SET_STRING +#undef SET_RESULT return v; + +error: + Py_DECREF(v); + return NULL; } /*[clinic input] From 03707c82d28986848ab50e194c8edf70c0d1576f Mon Sep 17 00:00:00 2001 From: sobolevn Date: Sat, 9 Mar 2024 21:07:10 +0300 Subject: [PATCH 2/2] Address review --- Modules/pwdmodule.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c index 1997e308201fb40..c59a8e41aa292a3 100644 --- a/Modules/pwdmodule.c +++ b/Modules/pwdmodule.c @@ -74,20 +74,8 @@ mkpwent(PyObject *module, struct passwd *p) int setIndex = 0; -#define SET_STRING(VAL) \ - do { \ - const char* val = (VAL); \ - if (val) { \ - PyObject *obj = PyUnicode_DecodeFSDefault(val); \ - if (obj == NULL) { \ - goto error; \ - } \ - PyStructSequence_SET_ITEM(v, setIndex++, obj); \ - } \ - else { \ - PyStructSequence_SET_ITEM(v, setIndex++, Py_NewRef(Py_None)); \ - } \ - } while(0) +#define SET_STRING(VAL) \ + SET_RESULT((VAL) ? PyUnicode_DecodeFSDefault((VAL)) : Py_NewRef(Py_None)) #define SET_RESULT(CALL) \ do { \