Skip to content

Commit 538f0eb

Browse files
committed
gh-160782: reject symlinked subdirectories in the venv directory
1 parent 4a9b981 commit 538f0eb

3 files changed

Lines changed: 25 additions & 0 deletions

File tree

‎Lib/test/test_venv.py‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -663,6 +663,23 @@ def test_unoverwritable_fails(self):
663663
self.assertRaises((ValueError, OSError), venv.create, self.env_dir)
664664
self.clear_directory(self.env_dir)
665665

666+
@unittest.skipUnless(can_symlink(), 'Needs symlinks')
667+
def test_symlinked_directory_error(self):
668+
"""
669+
Test that venv creation fails when a directory inside the target
670+
directory is a symlink.
671+
"""
672+
outside = tempfile.mkdtemp()
673+
self.addCleanup(rmtree, outside)
674+
for subdirs in self.ENV_SUBDIRS:
675+
with self.subTest(subdirs=subdirs):
676+
rmtree(self.env_dir)
677+
os.makedirs(os.path.join(self.env_dir, *subdirs[:-1]))
678+
os.symlink(outside, os.path.join(self.env_dir, *subdirs),
679+
target_is_directory=True)
680+
self.assertRaises(ValueError, venv.create, self.env_dir)
681+
self.assertEqual(os.listdir(outside), [])
682+
666683
def test_upgrade(self):
667684
"""
668685
Test upgrading an existing environment directory.

‎Lib/venv/__init__.py‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,12 @@ def ensure_directories(self, env_dir):
141141
"""
142142

143143
def create_if_needed(d):
144+
path = env_dir
145+
for part in os.path.relpath(d, env_dir).split(os.sep)[:-1]:
146+
path = os.path.join(path, part)
147+
if os.path.islink(path) or os.path.isjunction(path):
148+
raise ValueError(f'Refusing to create a venv in {env_dir} '
149+
f'because {path} is a link.')
144150
if not os.path.exists(d):
145151
os.makedirs(d)
146152
elif os.path.islink(d) or os.path.isfile(d):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`venv`: a symbolic link or junction in place of a directory inside the
2+
environment now raises :exc:`ValueError` instead of being followed.

0 commit comments

Comments
 (0)