summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@redhat.com>2018-12-18 17:34:51 +0100
committerGitHub <noreply@github.com>2018-12-18 17:34:51 +0100
commitea6b322829c62951362f267d7afdd262aa2b3e2c (patch)
tree2e29bb8cad9bc5eeb3e1456947a8ba253c45a5b9
parent34b7c438b8dc0a1e7e23c9b2d7ce7f8a7c31b4f4 (diff)
downloadcpython-git-ea6b322829c62951362f267d7afdd262aa2b3e2c.tar.gz
bpo-10496: distutils check_environ() handles getpwuid() error (GH-10931) (GH-11213)
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)
-rw-r--r--Lib/distutils/tests/test_util.py42
-rw-r--r--Lib/distutils/util.py9
-rw-r--r--Misc/NEWS.d/next/Library/2018-12-05-17-42-49.bpo-10496.laV_IE.rst3
3 files changed, 50 insertions, 4 deletions
diff --git a/Lib/distutils/tests/test_util.py b/Lib/distutils/tests/test_util.py
index 7898e07b25..e081709729 100644
--- a/Lib/distutils/tests/test_util.py
+++ b/Lib/distutils/tests/test_util.py
@@ -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)
diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py
index 2b4d7849bd..5a06b8597c 100644
--- a/Lib/distutils/util.py
+++ b/Lib/distutils/util.py
@@ -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
index 0000000000..cbfe5eb116
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-12-05-17-42-49.bpo-10496.laV_IE.rst
@@ -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.