summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2023-11-11 08:02:08 (GMT)
committerGitHub <noreply@github.com>2023-11-11 08:02:08 (GMT)
commit3bd8b743305f0d788302df3ff08c2bb7eb0dd297 (patch)
treec4c93dd39729a413ef3a4517144696a5e8f62fce
parent2c6000cba496ed572a682a41ba20a1b58534c45a (diff)
downloadcpython-3bd8b743305f0d788302df3ff08c2bb7eb0dd297.zip
cpython-3bd8b743305f0d788302df3ff08c2bb7eb0dd297.tar.gz
cpython-3bd8b743305f0d788302df3ff08c2bb7eb0dd297.tar.bz2
[3.12] gh-111841: Fix os.putenv() and os.unsetenv() with embedded NUL on Windows (GH-111842) (GH-111966)
(cherry picked from commit 0b06d2482d77e02c5d40e221f6046c9c355458b2) Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
-rw-r--r--Lib/test/test_os.py5
-rw-r--r--Lib/test/test_posix.py14
-rw-r--r--Misc/NEWS.d/next/Library/2023-11-08-11-50-49.gh-issue-111841.iSqdQf.rst2
-rw-r--r--Modules/posixmodule.c7
4 files changed, 19 insertions, 9 deletions
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index 38464c6..1f0836b 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -1142,9 +1142,12 @@ class EnvironTests(mapping_tests.BasicTestMappingProtocol):
def test_putenv_unsetenv_error(self):
# Empty variable name is invalid.
# "=" and null character are not allowed in a variable name.
- for name in ('', '=name', 'na=me', 'name=', 'name\0', 'na\0me'):
+ for name in ('', '=name', 'na=me', 'name='):
self.assertRaises((OSError, ValueError), os.putenv, name, "value")
self.assertRaises((OSError, ValueError), os.unsetenv, name)
+ for name in ('name\0', 'na\0me'):
+ self.assertRaises(ValueError, os.putenv, name, "value")
+ self.assertRaises(ValueError, os.unsetenv, name)
if sys.platform == "win32":
# On Windows, an environment variable string ("name=value" string)
diff --git a/Lib/test/test_posix.py b/Lib/test/test_posix.py
index 7440779..1722c84 100644
--- a/Lib/test/test_posix.py
+++ b/Lib/test/test_posix.py
@@ -1011,20 +1011,20 @@ class PosixTester(unittest.TestCase):
self.assertEqual(type(k), item_type)
self.assertEqual(type(v), item_type)
- @unittest.skipUnless(os.name == 'posix', "see bug gh-111841")
def test_putenv(self):
with self.assertRaises(ValueError):
os.putenv('FRUIT\0VEGETABLE', 'cabbage')
with self.assertRaises(ValueError):
- os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
- with self.assertRaises(ValueError):
os.putenv('FRUIT', 'orange\0VEGETABLE=cabbage')
with self.assertRaises(ValueError):
- os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
- with self.assertRaises(ValueError):
os.putenv('FRUIT=ORANGE', 'lemon')
- with self.assertRaises(ValueError):
- os.putenv(b'FRUIT=ORANGE', b'lemon')
+ if os.name == 'posix':
+ with self.assertRaises(ValueError):
+ os.putenv(b'FRUIT\0VEGETABLE', b'cabbage')
+ with self.assertRaises(ValueError):
+ os.putenv(b'FRUIT', b'orange\0VEGETABLE=cabbage')
+ with self.assertRaises(ValueError):
+ os.putenv(b'FRUIT=ORANGE', b'lemon')
@unittest.skipUnless(hasattr(posix, 'getcwd'), 'test needs posix.getcwd()')
def test_getcwd_long_pathnames(self):
diff --git a/Misc/NEWS.d/next/Library/2023-11-08-11-50-49.gh-issue-111841.iSqdQf.rst b/Misc/NEWS.d/next/Library/2023-11-08-11-50-49.gh-issue-111841.iSqdQf.rst
new file mode 100644
index 0000000..cd17809
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2023-11-08-11-50-49.gh-issue-111841.iSqdQf.rst
@@ -0,0 +1,2 @@
+Fix truncating arguments on an embedded null character in :meth:`os.putenv`
+and :meth:`os.unsetenv` on Windows.
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index a98841f..0ac5a8d 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -12006,7 +12006,6 @@ win32_putenv(PyObject *name, PyObject *value)
}
Py_ssize_t size;
- /* PyUnicode_AsWideCharString() rejects embedded null characters */
wchar_t *env = PyUnicode_AsWideCharString(unicode, &size);
Py_DECREF(unicode);
@@ -12020,6 +12019,12 @@ win32_putenv(PyObject *name, PyObject *value)
PyMem_Free(env);
return NULL;
}
+ if (wcslen(env) != (size_t)size) {
+ PyErr_SetString(PyExc_ValueError,
+ "embedded null character");
+ PyMem_Free(env);
+ return NULL;
+ }
/* _wputenv() and SetEnvironmentVariableW() update the environment in the
Process Environment Block (PEB). _wputenv() also updates CRT 'environ'