]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-10496: distutils check_environ() handles getpwuid() error (GH-10931) (GH-11213)
authorVictor Stinner <vstinner@redhat.com>
Tue, 18 Dec 2018 16:34:51 +0000 (17:34 +0100)
committerGitHub <noreply@github.com>
Tue, 18 Dec 2018 16:34:51 +0000 (17:34 +0100)
check_environ() of distutils.utils now catchs KeyError on calling
pwd.getpwuid(): don't create the HOME environment variable in this
case.

(cherry picked from commit 17d0c0595e101c4ce76b58e55de37e6b5083e6cd)

Lib/distutils/tests/test_util.py
Lib/distutils/util.py
Misc/NEWS.d/next/Library/2018-12-05-17-42-49.bpo-10496.laV_IE.rst [new file with mode: 0644]

index 7898e07b2517145f1c5c21fdd8d258ef277c8859..e0817097296d6a3400fc9cc03f30ed3467bd668d 100644 (file)
@@ -1,11 +1,14 @@
 """Tests for distutils.util."""
+import os
 import sys
 import unittest
-from test.test_support import run_unittest
+from test.test_support import run_unittest, swap_attr
 
 from distutils.errors import DistutilsByteCompileError
 from distutils.tests import support
-from distutils.util import byte_compile, grok_environment_error
+from distutils import util # used to patch _environ_checked
+from distutils.util import (byte_compile, grok_environment_error,
+                            check_environ, get_platform)
 
 
 class UtilTestCase(support.EnvironGuard, unittest.TestCase):
@@ -26,6 +29,41 @@ class UtilTestCase(support.EnvironGuard, unittest.TestCase):
         msg = grok_environment_error(exc)
         self.assertEqual(msg, "error: Unable to find batch file")
 
+    def test_check_environ(self):
+        util._environ_checked = 0
+        os.environ.pop('HOME', None)
+
+        check_environ()
+
+        self.assertEqual(os.environ['PLAT'], get_platform())
+        self.assertEqual(util._environ_checked, 1)
+
+    @unittest.skipUnless(os.name == 'posix', 'specific to posix')
+    def test_check_environ_getpwuid(self):
+        util._environ_checked = 0
+        os.environ.pop('HOME', None)
+
+        import pwd
+
+        # only set pw_dir field, other fields are not used
+        def mock_getpwuid(uid):
+            return pwd.struct_passwd((None, None, None, None, None,
+                                      '/home/distutils', None))
+
+        with swap_attr(pwd, 'getpwuid', mock_getpwuid):
+            check_environ()
+            self.assertEqual(os.environ['HOME'], '/home/distutils')
+
+        util._environ_checked = 0
+        os.environ.pop('HOME', None)
+
+        # bpo-10496: Catch pwd.getpwuid() error
+        def getpwuid_err(uid):
+            raise KeyError
+        with swap_attr(pwd, 'getpwuid', getpwuid_err):
+            check_environ()
+            self.assertNotIn('HOME', os.environ)
+
 
 def test_suite():
     return unittest.makeSuite(UtilTestCase)
index 2b4d7849bdccf1d019b4a1d8702e5d290e552feb..5a06b8597c6e84b6f0fda60eed540825034036bb 100644 (file)
@@ -178,8 +178,13 @@ def check_environ ():
         return
 
     if os.name == 'posix' and 'HOME' not in os.environ:
-        import pwd
-        os.environ['HOME'] = pwd.getpwuid(os.getuid())[5]
+        try:
+            import pwd
+            os.environ['HOME'] = pwd.getpwuid(os.getuid())[5]
+        except (ImportError, KeyError):
+            # bpo-10496: if the current user identifier doesn't exist in the
+            # password database, do nothing
+            pass
 
     if 'PLAT' not in os.environ:
         os.environ['PLAT'] = get_platform()
diff --git a/Misc/NEWS.d/next/Library/2018-12-05-17-42-49.bpo-10496.laV_IE.rst b/Misc/NEWS.d/next/Library/2018-12-05-17-42-49.bpo-10496.laV_IE.rst
new file mode 100644 (file)
index 0000000..cbfe5eb
--- /dev/null
@@ -0,0 +1,3 @@
+:func:`~distutils.utils.check_environ` of :mod:`distutils.utils` now catchs
+:exc:`KeyError` on calling :func:`pwd.getpwuid`: don't create the ``HOME``
+environment variable in this case.