In pwd, spwd and grp modules, make the get*nam() functions encode their arguments using the file system encoding and the "surrogateescape" error handler. Index: Modules/pwdmodule.c =================================================================== --- Modules/pwdmodule.c.orig +++ Modules/pwdmodule.c @@ -130,14 +130,25 @@ { char *name; struct passwd *p; - if (!PyArg_ParseTuple(args, "s:getpwnam", &name)) + PyObject *arg, *bytes, *retval = NULL; + + if (!PyArg_ParseTuple(args, "U:getpwnam", &arg)) + return NULL; + if ((bytes = PyUnicode_AsEncodedString(arg, + Py_FileSystemDefaultEncoding, + "surrogateescape")) == NULL) return NULL; + if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) + goto out; if ((p = getpwnam(name)) == NULL) { PyErr_Format(PyExc_KeyError, "getpwnam(): name not found: %s", name); - return NULL; + goto out; } - return mkpwent(p); + retval = mkpwent(p); +out: + Py_DECREF(bytes); + return retval; } #ifdef HAVE_GETPWENT Index: Modules/spwdmodule.c =================================================================== --- Modules/spwdmodule.c.orig +++ Modules/spwdmodule.c @@ -116,13 +116,24 @@ { char *name; struct spwd *p; - if (!PyArg_ParseTuple(args, "s:getspnam", &name)) + PyObject *arg, *bytes, *retval = NULL; + + if (!PyArg_ParseTuple(args, "U:getspnam", &arg)) + return NULL; + if ((bytes = PyUnicode_AsEncodedString(arg, + Py_FileSystemDefaultEncoding, + "surrogateescape")) == NULL) return NULL; + if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) + goto out; if ((p = getspnam(name)) == NULL) { PyErr_SetString(PyExc_KeyError, "getspnam(): name not found"); - return NULL; + goto out; } - return mkspent(p); + retval = mkspent(p); +out: + Py_DECREF(bytes); + return retval; } #endif /* HAVE_GETSPNAM */ Index: Modules/grpmodule.c =================================================================== --- Modules/grpmodule.c.orig +++ Modules/grpmodule.c @@ -107,25 +107,28 @@ } static PyObject * -grp_getgrnam(PyObject *self, PyObject *pyo_name) +grp_getgrnam(PyObject *self, PyObject *args) { - PyObject *py_str_name; char *name; struct group *p; + PyObject *arg, *bytes, *retval = NULL; - py_str_name = PyObject_Str(pyo_name); - if (!py_str_name) - return NULL; - name = _PyUnicode_AsString(py_str_name); + if (!PyArg_ParseTuple(args, "U:getgrnam", &arg)) + return NULL; + if ((bytes = PyUnicode_AsEncodedString(arg, Py_FileSystemDefaultEncoding, + "surrogateescape")) == NULL) + return NULL; + if (PyBytes_AsStringAndSize(bytes, &name, NULL) == -1) + goto out; if ((p = getgrnam(name)) == NULL) { PyErr_Format(PyExc_KeyError, "getgrnam(): name not found: %s", name); - Py_DECREF(py_str_name); - return NULL; + goto out; } - - Py_DECREF(py_str_name); - return mkgrent(p); + retval = mkgrent(p); +out: + Py_DECREF(bytes); + return retval; } static PyObject * @@ -155,7 +158,7 @@ "getgrgid(id) -> tuple\n\ Return the group database entry for the given numeric group ID. If\n\ id is not valid, raise KeyError."}, - {"getgrnam", grp_getgrnam, METH_O, + {"getgrnam", grp_getgrnam, METH_VARARGS, "getgrnam(name) -> tuple\n\ Return the group database entry for the given group name. If\n\ name is not valid, raise KeyError."},