]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-111841: Fix os.putenv() and os.unsetenv() with embedded NUL on Windows...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Sat, 11 Nov 2023 09:17:29 +0000 (10:17 +0100)
committerGitHub <noreply@github.com>
Sat, 11 Nov 2023 09:17:29 +0000 (11:17 +0200)
(cherry picked from commit 0b06d2482d77e02c5d40e221f6046c9c355458b2)

Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Lib/test/test_os.py
Lib/test/test_posix.py
Misc/NEWS.d/next/Library/2023-11-08-11-50-49.gh-issue-111841.iSqdQf.rst [new file with mode: 0644]
Modules/posixmodule.c

index ff1121efdf74daf89a192fad203dfa7960be71c3..441e1f977a55d37da7bbfc390632729a468762d1 100644 (file)
@@ -1130,9 +1130,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)
index 912f07ec4436b56afb9863d8282a88450ccfff1a..0b1068bfff6ff9098e3b911b23606d6f5b03be09 100644 (file)
@@ -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 (file)
index 0000000..cd17809
--- /dev/null
@@ -0,0 +1,2 @@
+Fix truncating arguments on an embedded null character in :meth:`os.putenv`
+and :meth:`os.unsetenv` on Windows.
index 18e983e5aa1d99e1ba015c18cee308377c5be21b..9ac021f6c5f8b0984e1220bedb65d956263746fc 100644 (file)
@@ -11102,7 +11102,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);
 
@@ -11116,6 +11115,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'