diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 4803790b9..df003c7d3 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -8,6 +8,7 @@ Changelog Security fixes for * https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-gq48-pqfc-9p58 +* https://github.com/gitpython-developers/GitPython/security/advisories/GHSA-23mf-xhv8-69c2 If you can, also try and provide feedback on the upcoming v4 branch https://github.com/gitpython-developers/GitPython/pull/2177 - patches welcome. diff --git a/git/refs/head.py b/git/refs/head.py index 7f563374e..5dd4a5a0a 100644 --- a/git/refs/head.py +++ b/git/refs/head.py @@ -283,7 +283,7 @@ def checkout( """ if not allow_unsafe_options: Git.check_unsafe_options( - options=Git._option_candidates([], kwargs), + options=Git._option_candidates([self], kwargs), unsafe_options=Git.unsafe_git_pathspec_from_file_options, ) kwargs["f"] = force diff --git a/test/test_refs.py b/test/test_refs.py index 32c8fbe34..ae3687c30 100644 --- a/test/test_refs.py +++ b/test/test_refs.py @@ -289,6 +289,25 @@ def test_head_checkout_rejects_pathspec_from_file(self, rw_repo): pathspec_file_nul=True, **{option_name: str(pathspecs)}, ) + for option_name in ("--pathspec-from-file", "--pathspec-from"): + branch = Head(rw_repo, f"refs/heads/{option_name}={pathspecs}") + with self.assertRaises(UnsafeOptionError): + branch.checkout() + + def test_cloned_head_checkout_rejects_pathspec_from_file(self): + with tempfile.TemporaryDirectory() as tdir: + base_dir = Path(tdir) + with self._repo_with_initial_commit(base_dir) as source: + branch = source.create_head("--pathspec-from-file=pathspecs") + source.head.reference = branch + with Repo.clone_from(source.working_tree_dir, base_dir / "clone") as cloned: + (base_dir / "clone" / "pathspecs").write_text("unmatched-private-content\n", encoding="utf-8") + assert cloned.active_branch.name == branch.name + with self.assertRaises(UnsafeOptionError): + cloned.active_branch.checkout() + with self.assertRaises(GitCommandError) as error: + cloned.active_branch.checkout(allow_unsafe_options=True) + assert "unmatched-private-content" in str(error.exception) @with_rw_repo("HEAD") def test_head_reset_rejects_pathspec_from_file(self, rw_repo):