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 @@ -447,6 +447,15 @@ class EnvironTests(mapping_tests.BasicTe value_str = value.decode(sys.getfilesystemencoding(), 'surrogateescape') self.assertEqual(os.environ['bytes'], value_str) + def test_unset_error(self): + if sys.platform == "win32": + # an environment variable is limited to 32,767 characters + key = 'x' * 50000 + else: + # "=" is not allowed in a variable name + key = 'key=' + self.assertRaises(OSError, os.environ.__delitem__, key) + class WalkTests(unittest.TestCase): """Tests for os.walk().""" diff --git a/Misc/NEWS b/Misc/NEWS --- a/Misc/NEWS +++ b/Misc/NEWS @@ -377,6 +377,8 @@ Core and Builtins Library ------- +- Issue #13415: os.unsetenv() doesn't ignore errors anymore. + - Issue #13374: The Windows bytes API has been deprecated in the os module. Use Unicode filenames instead of bytes filenames to not depend on the ANSI code page anymore and to support any filename. diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -7800,6 +7800,12 @@ posix_putenv(PyObject *self, PyObject *a PyBytes_FromStringAndSize does not count that */ #ifdef MS_WINDOWS len = wcslen(s1) + wcslen(s2) + 2; + if (_MAX_ENV < (len - 1)) { + PyErr_Format(PyExc_ValueError, + "the environment variable is longer than %u characters", + _MAX_ENV); + goto error; + } newstr = PyUnicode_FromUnicode(NULL, (int)len - 1); #else len = PyBytes_GET_SIZE(os1) + PyBytes_GET_SIZE(os2) + 2; @@ -7873,42 +7879,27 @@ Delete an environment variable."); static PyObject * posix_unsetenv(PyObject *self, PyObject *args) { -#ifdef MS_WINDOWS - char *s1; - - if (!PyArg_ParseTuple(args, "s:unsetenv", &s1)) - return NULL; -#else - PyObject *os1; - char *s1; + PyObject *name; + int err; if (!PyArg_ParseTuple(args, "O&:unsetenv", - PyUnicode_FSConverter, &os1)) - return NULL; - s1 = PyBytes_AsString(os1); -#endif - - unsetenv(s1); + PyUnicode_FSConverter, &name)) + return NULL; + + err = unsetenv(PyBytes_AS_STRING(name)); + if (err) + return posix_error(); /* Remove the key from posix_putenv_garbage; * this will cause it to be collected. This has to * happen after the real unsetenv() call because the * old value was still accessible until then. */ - if (PyDict_DelItem(posix_putenv_garbage, -#ifdef MS_WINDOWS - PyTuple_GET_ITEM(args, 0) -#else - os1 -#endif - )) { + if (PyDict_DelItem(posix_putenv_garbage, name)) { /* really not much we can do; just leak */ PyErr_Clear(); } - -#ifndef MS_WINDOWS - Py_DECREF(os1); -#endif + Py_DECREF(name); Py_RETURN_NONE; } #endif /* unsetenv */