Make posix.putenv() raise ValueError if name is empty. diff --git a/Doc/library/os.rst b/Doc/library/os.rst --- a/Doc/library/os.rst +++ b/Doc/library/os.rst @@ -253,8 +253,8 @@ process and user. Set the environment variable named *varname* to the string *value*. Such changes to the environment affect subprocesses started with :func:`os.system`, - :func:`popen` or :func:`fork` and :func:`execv`. Raises :exc:`ValueError` - if *varname* contains an ``'='`` character. + :func:`popen` or :func:`fork` and :func:`execv`. May raise + :exc:`ValueError` if *varname* is empty or contains an ``'='`` character. Availability: most flavors of Unix, Windows. diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -352,6 +352,8 @@ class EnvironTests(mapping_tests.BasicTe "PYTHONTESTVAROS=SOMETHING", "value") self.assertTrue("PYTHONTESTVAROS=SOMETHING" not in os.environ) self.assertTrue("PYTHONTESTVAROS" not in os.environ) + self.assertRaises(ValueError, os.environ.__setitem__, "", "value") + self.assertTrue("" not in os.environ) class WalkTests(unittest.TestCase): """Tests for os.walk().""" diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py --- a/Lib/test/test_posix.py +++ b/Lib/test/test_posix.py @@ -340,6 +340,7 @@ class PosixTester(unittest.TestCase): # See issue #4926 self.assertRaises(ValueError, posix.putenv, "PYTHONTESTVARB=SOMETHING", "value") + self.assertRaises(ValueError, posix.putenv, "", "value") def test_getcwd_long_pathnames(self): if hasattr(posix, 'getcwd'): diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -6868,6 +6868,21 @@ posix_putenv(PyObject *self, PyObject *a if (!PyArg_ParseTuple(args, "ss:putenv", &s1, &s2)) return NULL; + /* XXX: logically, there is no problem with an environment + variable having an empty name, but POSIX requires unsetenv() to + refuse to delete such a variable, which can be a problem (on + Linux, for instance, such a variable can be passed to a new + process, but cannot be deleted with unsetenv()). The return + value of unsetenv() is currently not checked (some systems + declare it as void), so an object added to posix_putenv_garbage + for an empty-named variable could be freed while the + environment still pointed into it. */ + if (*s1 == 0) { + PyErr_SetString(PyExc_ValueError, "environment variable name must " + "not be empty"); + return NULL; + } + /* An '=' character would be interpreted as the end of the name. */ if (strchr(s1, '=') != NULL) { PyErr_SetString(PyExc_ValueError, "environment variable name must "