Index: Doc/library/os.rst =================================================================== --- Doc/library/os.rst (revision 68535) +++ Doc/library/os.rst (working copy) @@ -203,8 +203,9 @@ 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`. Availability: most flavors of - Unix, Windows. + :func:`popen` or :func:`fork` and :func:`execv`. Raises :exc:`ValueError` + if *varname* contains an '=' character. + Availability: most flavors of Unix, Windows. .. note:: @@ -322,7 +323,9 @@ Unset (delete) the environment variable named *varname*. Such changes to the environment affect subprocesses started with :func:`os.system`, :func:`popen` or - :func:`fork` and :func:`execv`. Availability: most flavors of Unix, Windows. + :func:`fork` and :func:`execv`. Raises :exc:`OSError` if *varname* is + invalid, for example if it contains an '=' character. + Availability: most flavors of Unix, Windows. When :func:`unsetenv` is supported, deletion of items in ``os.environ`` is automatically translated into a corresponding call to :func:`unsetenv`; however, Index: Lib/test/test_posix.py =================================================================== --- Lib/test/test_posix.py (revision 68535) +++ Lib/test/test_posix.py (working copy) @@ -232,6 +232,23 @@ if hasattr(st, 'st_flags'): posix.lchflags(test_support.TESTFN, st.st_flags) + def test_putenv(self): + if hasattr(posix, 'putenv'): + posix.putenv("TESTTEST", "test") + posix.putenv("TESTTEST", "newvalue") + self.assertRaises(ValueError, posix.putenv, "FOO=BAR", "value") + + def test_unsetenv(self): + if hasattr(posix, 'unsetenv'): + posix.putenv("TESTTEST", "test") + posix.unsetenv("TESTTEST") + posix.unsetenv("TESTTEST") + posix.unsetenv("BLAHBLAH") + posix.unsetenv("BLAHBLAH") + # POSIX requires unsetenv to fail here; the posix module + # originally didn't check the return value. + self.assertRaises(OSError, posix.unsetenv, "BAR=BAZ") + def test_getcwd_long_pathnames(self): if hasattr(posix, 'getcwd'): dirname = 'getcwd-test-directory-0123456789abcdef-01234567890abcdef' Index: Modules/posixmodule.c =================================================================== --- Modules/posixmodule.c (revision 68535) +++ Modules/posixmodule.c (working copy) @@ -6678,6 +6678,12 @@ } else { #endif + if (strchr(s1, '=') != NULL) { + PyErr_SetString(PyExc_ValueError, "environment variable names " + "may not contain the '=' character"); + return NULL; + } + /* XXX This can leak memory -- not easy to fix :-( */ len = strlen(s1) + strlen(s2) + 2; /* len includes space for a trailing \0; the size arg to @@ -6726,7 +6732,8 @@ if (!PyArg_ParseTuple(args, "s:unsetenv", &s1)) return NULL; - unsetenv(s1); + if (unsetenv(s1)) + return posix_error(); /* Remove the key from posix_putenv_garbage; * this will cause it to be collected. This has to