From c90e7fe73e1ecb35bce0b9afd1cb9e44bf08a1e5 Mon Sep 17 00:00:00 2001 From: Neko Asakura Date: Fri, 30 Oct 2026 10:32:14 -0400 Subject: [PATCH] gh-160782: reject line breaks in the venv directory and prompt --- Lib/test/test_venv.py | 17 +++++++++++++++++ Lib/venv/__init__.py | 7 +++++++ ...26-10-30-09-59-22.gh-issue-160782.fN0HIu.rst | 2 ++ 3 files changed, 26 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2026-10-30-09-59-22.gh-issue-160782.fN0HIu.rst diff --git a/Lib/test/test_venv.py b/Lib/test/test_venv.py index 678615ea172aefa..9e879cd901ace96 100644 --- a/Lib/test/test_venv.py +++ b/Lib/test/test_venv.py @@ -1075,6 +1075,23 @@ def test_pathsep_error(self): self.assertRaises(ValueError, venv.create, bad_itempath) self.assertRaises(ValueError, venv.create, FakePath(bad_itempath)) + def test_line_break_error(self): + """ + Test that venv creation fails when the target directory or the + prompt contains a line break. + """ + rmtree(self.env_dir) + for line_break in '\n', '\r': + with self.subTest(line_break=line_break): + bad_itempath = f'{self.env_dir}{line_break}x' + self.assertRaises(ValueError, venv.create, bad_itempath) + self.assertRaises(ValueError, venv.create, + FakePath(bad_itempath)) + bad_prompt = f'x{line_break}x' + self.assertRaises(ValueError, venv.create, self.env_dir, + prompt=bad_prompt) + self.assertFalse(os.path.exists(self.env_dir)) + @unittest.skipIf(os.name == 'nt', 'not relevant on Windows') @requireVenvCreate def test_zippath_from_non_installed_posix(self): diff --git a/Lib/venv/__init__.py b/Lib/venv/__init__.py index 620168be16862ec..501070b9185083a 100644 --- a/Lib/venv/__init__.py +++ b/Lib/venv/__init__.py @@ -149,6 +149,13 @@ def create_if_needed(d): if os.pathsep in os.fspath(env_dir): raise ValueError(f'Refusing to create a venv in {env_dir} because ' f'it contains the PATH separator {os.pathsep}.') + if '\n' in os.fspath(env_dir) or '\r' in os.fspath(env_dir): + raise ValueError(f'Refusing to create a venv in {env_dir!r} ' + 'because its path contains a line break.') + if self.prompt is not None and ('\n' in self.prompt + or '\r' in self.prompt): + raise ValueError(f'Refusing to use the prompt {self.prompt!r} ' + 'because it contains a line break.') if os.path.exists(env_dir) and self.clear: self.clear_directory(env_dir) context = types.SimpleNamespace() diff --git a/Misc/NEWS.d/next/Library/2026-10-30-09-59-22.gh-issue-160782.fN0HIu.rst b/Misc/NEWS.d/next/Library/2026-10-30-09-59-22.gh-issue-160782.fN0HIu.rst new file mode 100644 index 000000000000000..c69ee6ac18f5bd4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-30-09-59-22.gh-issue-160782.fN0HIu.rst @@ -0,0 +1,2 @@ +:mod:`venv`: a line break in the prompt or the path now raises +:exc:`ValueError` instead of being written into ``pyvenv.cfg``.