From 17d0c0595e101c4ce76b58e55de37e6b5083e6cd Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Tue, 18 Dec 2018 16:17:56 +0100 Subject: [PATCH] bpo-10496: distutils check_environ() handles getpwuid() error (GH-10931) check_environ() of distutils.utils now catchs KeyError on calling pwd.getpwuid(): don't create the HOME environment variable in this case. --- Lib/distutils/tests/test_util.py | 34 ++++++++++++++----- Lib/distutils/util.py | 9 +++-- .../2018-12-05-17-42-49.bpo-10496.laV_IE.rst | 3 ++ 3 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2018-12-05-17-42-49.bpo-10496.laV_IE.rst diff --git a/Lib/distutils/tests/test_util.py b/Lib/distutils/tests/test_util.py index e2fc380958..bf0d4333f9 100644 --- a/Lib/distutils/tests/test_util.py +++ b/Lib/distutils/tests/test_util.py @@ -4,6 +4,7 @@ import sys import unittest from copy import copy from test.support import run_unittest +from unittest import mock from distutils.errors import DistutilsPlatformError, DistutilsByteCompileError from distutils.util import (get_platform, convert_path, change_root, @@ -234,20 +235,35 @@ class UtilTestCase(support.EnvironGuard, unittest.TestCase): def test_check_environ(self): util._environ_checked = 0 - if 'HOME' in os.environ: - del os.environ['HOME'] + os.environ.pop('HOME', None) - # posix without HOME - if os.name == 'posix': # this test won't run on windows - check_environ() - import pwd - self.assertEqual(os.environ['HOME'], pwd.getpwuid(os.getuid())[5]) - else: - check_environ() + 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 + result = pwd.struct_passwd((None, None, None, None, None, + '/home/distutils', None)) + with mock.patch.object(pwd, 'getpwuid', return_value=result): + check_environ() + self.assertEqual(os.environ['HOME'], '/home/distutils') + + util._environ_checked = 0 + os.environ.pop('HOME', None) + + # bpo-10496: Catch pwd.getpwuid() error + with mock.patch.object(pwd, 'getpwuid', side_effect=KeyError): + check_environ() + self.assertNotIn('HOME', os.environ) + def test_split_quoted(self): self.assertEqual(split_quoted('""one"" "two" \'three\' \\four'), ['one', 'two', 'three', 'four']) diff --git a/Lib/distutils/util.py b/Lib/distutils/util.py index 83682628ba..30a21e4afa 100644 --- a/Lib/distutils/util.py +++ b/Lib/distutils/util.py @@ -157,8 +157,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. -- 2.40.0