Skip to content

Commit 3bd8b74

Browse files
[3.12] gh-111841: Fix os.putenv() and os.unsetenv() with embedded NUL on Windows (GH-111842) (GH-111966)
(cherry picked from commit 0b06d24) Co-authored-by: Serhiy Storchaka <[email protected]>
1 parent 2c6000c commit 3bd8b74

File tree

4 files changed

+19
-9
lines changed

4 files changed

+19
-9
lines changed

Lib/test/test_os.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1142,9 +1142,12 @@ def test_putenv_unsetenv(self):
11421142
def test_putenv_unsetenv_error(self):
11431143
# Empty variable name is invalid.
11441144
# "=" and null character are not allowed in a variable name.
1145-
for name in ('', '=name', 'na=me', 'name=', 'name\0', 'na\0me'):
1145+
for name in ('', '=name', 'na=me', 'name='):
11461146
self.assertRaises((OSError, ValueError), os.putenv, name, "value")
11471147
self.assertRaises((OSError, ValueError), os.unsetenv, name)
1148+
for name in ('name\0', 'na\0me'):
1149+
self.assertRaises(ValueError, os.putenv, name, "value")
1150+
self.assertRaises(ValueError, os.unsetenv, name)
11481151

11491152
if sys.platform == "win32":
11501153
# On Windows, an environment variable string ("name=value" string)

Lib/test/test_posix.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,20 +1011,20 @@ def test_environ(self):
10111011
self.assertEqual(type(k), item_type)
10121012
self.assertEqual(type(v), item_type)
10131013

1014-
@unittest.skipUnless(os.name == 'posix', "see bug gh-111841")
10151014
def test_putenv(self):
10161015
with self.assertRaises(ValueError):
10171016
os.putenv('FRUIT\0VEGETABLE', 'cabbage')
1018-
with self.assertRaises(ValueError):
1019-
os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
10201017
with self.assertRaises(ValueError):
10211018
os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
1022-
with self.assertRaises(ValueError):
1023-
os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
10241019
with self.assertRaises(ValueError):
10251020
os.putenv('FRUIT=ORANGE', 'lemon')
1026-
with self.assertRaises(ValueError):
1027-
os.putenv(b'FRUIT=ORANGE', b'lemon')
1021+
if os.name == 'posix':
1022+
with self.assertRaises(ValueError):
1023+
os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
1024+
with self.assertRaises(ValueError):
1025+
os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
1026+
with self.assertRaises(ValueError):
1027+
os.putenv(b'FRUIT=ORANGE', b'lemon')
10281028

10291029
@unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
10301030
def test_getcwd_long_pathnames(self):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix truncating arguments on an embedded null character in :meth:`os.putenv`
2+
and :meth:`os.unsetenv` on Windows.

Modules/posixmodule.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12006,7 +12006,6 @@ win32_putenv(PyObject *name, PyObject *value)
1200612006
}
1200712007

1200812008
Py_ssize_t size;
12009-
/* PyUnicode_AsWideCharString() rejects embedded null characters */
1201012009
wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
1201112010
Py_DECREF(unicode);
1201212011

@@ -12020,6 +12019,12 @@ win32_putenv(PyObject *name, PyObject *value)
1202012019
PyMem_Free(env);
1202112020
return NULL;
1202212021
}
12022+
if (wcslen(env) != (size_t)size) {
12023+
PyErr_SetString(PyExc_ValueError,
12024+
"embedded null character");
12025+
PyMem_Free(env);
12026+
return NULL;
12027+
}
1202312028

1202412029
/* _wputenv() and SetEnvironmentVariableW() update the environment in the
1202512030
Process Environment Block (PEB). _wputenv() also updates CRT 'environ'

0 commit comments

Comments
 (0)