| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -272,7 +272,16 @@ def _module_abspath(cls, parent_repo: "Repo", path: PathLike, name: str) -> Path | |||
| 272 | 272 | # end | |
| 273 | 273 | ||
| 274 | 274 | @classmethod | |
| 275 | - def _clone_repo(cls, repo: "Repo", url: str, path: PathLike, name: str, **kwargs: Any) -> "Repo": | ||
| 275 | + def _clone_repo( | ||
| 276 | + cls, | ||
| 277 | + repo: "Repo", | ||
| 278 | + url: str, | ||
| 279 | + path: PathLike, | ||
| 280 | + name: str, | ||
| 281 | + allow_unsafe_options: bool = False, | ||
| 282 | + allow_unsafe_protocols: bool = False, | ||
| 283 | + **kwargs: Any, | ||
| 284 | + ) -> "Repo": | ||
| 276 | 285 | """:return: Repo instance of newly cloned repository | |
| 277 | 286 | :param repo: our parent repository | |
| 278 | 287 | :param url: url to clone from | |
@@ -289,7 +298,13 @@ def _clone_repo(cls, repo: "Repo", url: str, path: PathLike, name: str, **kwargs | |||
| 289 | 298 | module_checkout_path = osp.join(str(repo.working_tree_dir), path) | |
| 290 | 299 | # end | |
| 291 | 300 | ||
| 292 | - clone = git.Repo.clone_from(url, module_checkout_path, **kwargs) | ||
| 301 | + clone = git.Repo.clone_from( | ||
| 302 | + url, | ||
| 303 | + module_checkout_path, | ||
| 304 | + allow_unsafe_options=allow_unsafe_options, | ||
| 305 | + allow_unsafe_protocols=allow_unsafe_protocols, | ||
| 306 | + **kwargs, | ||
| 307 | + ) | ||
| 293 | 308 | if cls._need_gitfile_submodules(repo.git): | |
| 294 | 309 | cls._write_git_file_and_module_config(module_checkout_path, module_abspath) | |
| 295 | 310 | # end | |
@@ -359,6 +374,8 @@ def add( | |||
| 359 | 374 | depth: Union[int, None] = None, | |
| 360 | 375 | env: Union[Mapping[str, str], None] = None, | |
| 361 | 376 | clone_multi_options: Union[Sequence[TBD], None] = None, | |
| 377 | + allow_unsafe_options: bool = False, | ||
| 378 | + allow_unsafe_protocols: bool = False, | ||
| 362 | 379 | ) -> "Submodule": | |
| 363 | 380 | """Add a new submodule to the given repository. This will alter the index | |
| 364 | 381 | as well as the .gitmodules file, but will not create a new commit. | |
@@ -475,7 +492,16 @@ def add( | |||
| 475 | 492 | kwargs["multi_options"] = clone_multi_options | |
| 476 | 493 | ||
| 477 | 494 | # _clone_repo(cls, repo, url, path, name, **kwargs): | |
| 478 | - mrepo = cls._clone_repo(repo, url, path, name, env=env, **kwargs) | ||
| 495 | + mrepo = cls._clone_repo( | ||
| 496 | + repo, | ||
| 497 | + url, | ||
| 498 | + path, | ||
| 499 | + name, | ||
| 500 | + env=env, | ||
| 501 | + allow_unsafe_options=allow_unsafe_options, | ||
| 502 | + allow_unsafe_protocols=allow_unsafe_protocols, | ||
| 503 | + **kwargs, | ||
| 504 | + ) | ||
| 479 | 505 | # END verify url | |
| 480 | 506 | ||
| 481 | 507 | ## See #525 for ensuring git urls in config-files valid under Windows. | |
@@ -520,6 +546,8 @@ def update( | |||
| 520 | 546 | keep_going: bool = False, | |
| 521 | 547 | env: Union[Mapping[str, str], None] = None, | |
| 522 | 548 | clone_multi_options: Union[Sequence[TBD], None] = None, | |
| 549 | + allow_unsafe_options: bool = False, | ||
| 550 | + allow_unsafe_protocols: bool = False, | ||
| 523 | 551 | ) -> "Submodule": | |
| 524 | 552 | """Update the repository of this submodule to point to the checkout | |
| 525 | 553 | we point at with the binsha of this instance. | |
@@ -643,6 +671,8 @@ def update( | |||
| 643 | 671 | n=True, | |
| 644 | 672 | env=env, | |
| 645 | 673 | multi_options=clone_multi_options, | |
| 674 | + allow_unsafe_options=allow_unsafe_options, | ||
| 675 | + allow_unsafe_protocols=allow_unsafe_protocols, | ||
| 646 | 676 | ) | |
| 647 | 677 | # END handle dry-run | |
| 648 | 678 | progress.update( | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -658,9 +658,7 @@ def add_url(self, url: str, allow_unsafe_protocols: bool = False, **kwargs: Any) | |||
| 658 | 658 | :param url: string being the URL to add as an extra remote URL | |
| 659 | 659 | :return: self | |
| 660 | 660 | """ | |
| 661 | - if not allow_unsafe_protocols: | ||
| 662 | - Git.check_unsafe_protocols(url) | ||
| 663 | - return self.set_url(url, add=True) | ||
| 661 | + return self.set_url(url, add=True, allow_unsafe_protocols=allow_unsafe_protocols) | ||
| 664 | 662 | ||
| 665 | 663 | def delete_url(self, url: str, **kwargs: Any) -> "Remote": | |
| 666 | 664 | """Deletes a new url on current remote (special case of git remote set_url) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -23,6 +23,8 @@ | |||
| 23 | 23 | GitCommandError, | |
| 24 | 24 | ) | |
| 25 | 25 | from git.cmd import Git | |
| 26 | + from pathlib import Path | ||
| 27 | + from git.exc import UnsafeOptionError, UnsafeProtocolError | ||
| 26 | 28 | from test.lib import ( | |
| 27 | 29 | TestBase, | |
| 28 | 30 | with_rw_repo, | |
@@ -690,6 +692,215 @@ def test_push_error(self, repo): | |||
| 690 | 692 | with self.assertRaisesRegex(GitCommandError, "src refspec __BAD_REF__ does not match any"): | |
| 691 | 693 | rem.push("__BAD_REF__") | |
| 692 | 694 | ||
| 695 | + @with_rw_repo("HEAD") | ||
| 696 | + def test_set_unsafe_url(self, rw_repo): | ||
| 697 | + remote = rw_repo.remote("origin") | ||
| 698 | + urls = [ | ||
| 699 | + "ext::sh -c touch% /tmp/pwn", | ||
| 700 | + "fd::17/foo", | ||
| 701 | + ] | ||
| 702 | + for url in urls: | ||
| 703 | + with self.assertRaises(UnsafeProtocolError): | ||
| 704 | + remote.set_url(url) | ||
| 705 | + | ||
| 706 | + @with_rw_repo("HEAD") | ||
| 707 | + def test_set_unsafe_url_allowed(self, rw_repo): | ||
| 708 | + remote = rw_repo.remote("origin") | ||
| 709 | + urls = [ | ||
| 710 | + "ext::sh -c touch% /tmp/pwn", | ||
| 711 | + "fd::17/foo", | ||
| 712 | + ] | ||
| 713 | + for url in urls: | ||
| 714 | + remote.set_url(url, allow_unsafe_protocols=True) | ||
| 715 | + assert list(remote.urls)[-1] == url | ||
| 716 | + | ||
| 717 | + @with_rw_repo("HEAD") | ||
| 718 | + def test_add_unsafe_url(self, rw_repo): | ||
| 719 | + remote = rw_repo.remote("origin") | ||
| 720 | + urls = [ | ||
| 721 | + "ext::sh -c touch% /tmp/pwn", | ||
| 722 | + "fd::17/foo", | ||
| 723 | + ] | ||
| 724 | + for url in urls: | ||
| 725 | + with self.assertRaises(UnsafeProtocolError): | ||
| 726 | + remote.add_url(url) | ||
| 727 | + | ||
| 728 | + @with_rw_repo("HEAD") | ||
| 729 | + def test_add_unsafe_url_allowed(self, rw_repo): | ||
| 730 | + remote = rw_repo.remote("origin") | ||
| 731 | + urls = [ | ||
| 732 | + "ext::sh -c touch% /tmp/pwn", | ||
| 733 | + "fd::17/foo", | ||
| 734 | + ] | ||
| 735 | + for url in urls: | ||
| 736 | + remote.add_url(url, allow_unsafe_protocols=True) | ||
| 737 | + assert list(remote.urls)[-1] == url | ||
| 738 | + | ||
| 739 | + @with_rw_repo("HEAD") | ||
| 740 | + def test_create_remote_unsafe_url(self, rw_repo): | ||
| 741 | + urls = [ | ||
| 742 | + "ext::sh -c touch% /tmp/pwn", | ||
| 743 | + "fd::17/foo", | ||
| 744 | + ] | ||
| 745 | + for url in urls: | ||
| 746 | + with self.assertRaises(UnsafeProtocolError): | ||
| 747 | + Remote.create(rw_repo, "origin", url) | ||
| 748 | + | ||
| 749 | + @with_rw_repo("HEAD") | ||
| 750 | + def test_create_remote_unsafe_url_allowed(self, rw_repo): | ||
| 751 | + urls = [ | ||
| 752 | + "ext::sh -c touch% /tmp/pwn", | ||
| 753 | + "fd::17/foo", | ||
| 754 | + ] | ||
| 755 | + for i, url in enumerate(urls): | ||
| 756 | + remote = Remote.create(rw_repo, f"origin{i}", url, allow_unsafe_protocols=True) | ||
| 757 | + assert remote.url == url | ||
| 758 | + | ||
| 759 | + @with_rw_repo("HEAD") | ||
| 760 | + def test_fetch_unsafe_url(self, rw_repo): | ||
| 761 | + remote = rw_repo.remote("origin") | ||
| 762 | + urls = [ | ||
| 763 | + "ext::sh -c touch% /tmp/pwn", | ||
| 764 | + "fd::17/foo", | ||
| 765 | + ] | ||
| 766 | + for url in urls: | ||
| 767 | + with self.assertRaises(UnsafeProtocolError): | ||
| 768 | + remote.fetch(url) | ||
| 769 | + | ||
| 770 | + @with_rw_repo("HEAD") | ||
| 771 | + def test_fetch_unsafe_url_allowed(self, rw_repo): | ||
| 772 | + remote = rw_repo.remote("origin") | ||
| 773 | + urls = [ | ||
| 774 | + "ext::sh -c touch% /tmp/pwn", | ||
| 775 | + "fd::17/foo", | ||
| 776 | + ] | ||
| 777 | + for url in urls: | ||
| 778 | + # The URL will be allowed into the command, but the command will | ||
| 779 | + # fail since we don't have that protocol enabled in the Git config file. | ||
| 780 | + with self.assertRaises(GitCommandError): | ||
| 781 | + remote.fetch(url, allow_unsafe_protocols=True) | ||
| 782 | + | ||
| 783 | + @with_rw_repo("HEAD") | ||
| 784 | + def test_fetch_unsafe_options(self, rw_repo): | ||
| 785 | + remote = rw_repo.remote("origin") | ||
| 786 | + tmp_dir = Path(tempfile.mkdtemp()) | ||
| 787 | + tmp_file = tmp_dir / "pwn" | ||
| 788 | + unsafe_options = [{"upload-pack": f"touch {tmp_file}"}] | ||
| 789 | + for unsafe_option in unsafe_options: | ||
| 790 | + with self.assertRaises(UnsafeOptionError): | ||
| 791 | + remote.fetch(**unsafe_option) | ||
| 792 | + | ||
| 793 | + @with_rw_repo("HEAD") | ||
| 794 | + def test_fetch_unsafe_options_allowed(self, rw_repo): | ||
| 795 | + remote = rw_repo.remote("origin") | ||
| 796 | + tmp_dir = Path(tempfile.mkdtemp()) | ||
| 797 | + tmp_file = tmp_dir / "pwn" | ||
| 798 | + unsafe_options = [{"upload-pack": f"touch {tmp_file}"}] | ||
| 799 | + for unsafe_option in unsafe_options: | ||
| 800 | + # The options will be allowed, but the command will fail. | ||
| 801 | + with self.assertRaises(GitCommandError): | ||
| 802 | + remote.fetch(**unsafe_option, allow_unsafe_options=True) | ||
| 803 | + | ||
| 804 | + @with_rw_repo("HEAD") | ||
| 805 | + def test_pull_unsafe_url(self, rw_repo): | ||
| 806 | + remote = rw_repo.remote("origin") | ||
| 807 | + urls = [ | ||
| 808 | + "ext::sh -c touch% /tmp/pwn", | ||
| 809 | + "fd::17/foo", | ||
| 810 | + ] | ||
| 811 | + for url in urls: | ||
| 812 | + with self.assertRaises(UnsafeProtocolError): | ||
| 813 | + remote.pull(url) | ||
| 814 | + | ||
| 815 | + @with_rw_repo("HEAD") | ||
| 816 | + def test_pull_unsafe_url_allowed(self, rw_repo): | ||
| 817 | + remote = rw_repo.remote("origin") | ||
| 818 | + urls = [ | ||
| 819 | + "ext::sh -c touch% /tmp/pwn", | ||
| 820 | + "fd::17/foo", | ||
| 821 | + ] | ||
| 822 | + for url in urls: | ||
| 823 | + # The URL will be allowed into the command, but the command will | ||
| 824 | + # fail since we don't have that protocol enabled in the Git config file. | ||
| 825 | + with self.assertRaises(GitCommandError): | ||
| 826 | + remote.pull(url, allow_unsafe_protocols=True) | ||
| 827 | + | ||
| 828 | + @with_rw_repo("HEAD") | ||
| 829 | + def test_pull_unsafe_options(self, rw_repo): | ||
| 830 | + remote = rw_repo.remote("origin") | ||
| 831 | + tmp_dir = Path(tempfile.mkdtemp()) | ||
| 832 | + tmp_file = tmp_dir / "pwn" | ||
| 833 | + unsafe_options = [{"upload-pack": f"touch {tmp_file}"}] | ||
| 834 | + for unsafe_option in unsafe_options: | ||
| 835 | + with self.assertRaises(UnsafeOptionError): | ||
| 836 | + remote.pull(**unsafe_option) | ||
| 837 | + | ||
| 838 | + @with_rw_repo("HEAD") | ||
| 839 | + def test_pull_unsafe_options_allowed(self, rw_repo): | ||
| 840 | + remote = rw_repo.remote("origin") | ||
| 841 | + tmp_dir = Path(tempfile.mkdtemp()) | ||
| 842 | + tmp_file = tmp_dir / "pwn" | ||
| 843 | + unsafe_options = [{"upload-pack": f"touch {tmp_file}"}] | ||
| 844 | + for unsafe_option in unsafe_options: | ||
| 845 | + # The options will be allowed, but the command will fail. | ||
| 846 | + with self.assertRaises(GitCommandError): | ||
| 847 | + remote.pull(**unsafe_option, allow_unsafe_options=True) | ||
| 848 | + | ||
| 849 | + @with_rw_repo("HEAD") | ||
| 850 | + def test_push_unsafe_url(self, rw_repo): | ||
| 851 | + remote = rw_repo.remote("origin") | ||
| 852 | + urls = [ | ||
| 853 | + "ext::sh -c touch% /tmp/pwn", | ||
| 854 | + "fd::17/foo", | ||
| 855 | + ] | ||
| 856 | + for url in urls: | ||
| 857 | + with self.assertRaises(UnsafeProtocolError): | ||
| 858 | + remote.push(url) | ||
| 859 | + | ||
| 860 | + @with_rw_repo("HEAD") | ||
| 861 | + def test_push_unsafe_url_allowed(self, rw_repo): | ||
| 862 | + remote = rw_repo.remote("origin") | ||
| 863 | + urls = [ | ||
| 864 | + "ext::sh -c touch% /tmp/pwn", | ||
| 865 | + "fd::17/foo", | ||
| 866 | + ] | ||
| 867 | + for url in urls: | ||
| 868 | + # The URL will be allowed into the command, but the command will | ||
| 869 | + # fail since we don't have that protocol enabled in the Git config file. | ||
| 870 | + with self.assertRaises(GitCommandError): | ||
| 871 | + remote.push(url, allow_unsafe_protocols=True) | ||
| 872 | + | ||
| 873 | + @with_rw_repo("HEAD") | ||
| 874 | + def test_push_unsafe_options(self, rw_repo): | ||
| 875 | + remote = rw_repo.remote("origin") | ||
| 876 | + tmp_dir = Path(tempfile.mkdtemp()) | ||
| 877 | + tmp_file = tmp_dir / "pwn" | ||
| 878 | + unsafe_options = [ | ||
| 879 | + { | ||
| 880 | + "receive-pack": f"touch {tmp_file}", | ||
| 881 | + "exec": f"touch {tmp_file}", | ||
| 882 | + } | ||
| 883 | + ] | ||
| 884 | + for unsafe_option in unsafe_options: | ||
| 885 | + with self.assertRaises(UnsafeOptionError): | ||
| 886 | + remote.push(**unsafe_option) | ||
| 887 | + | ||
| 888 | + @with_rw_repo("HEAD") | ||
| 889 | + def test_push_unsafe_options_allowed(self, rw_repo): | ||
| 890 | + remote = rw_repo.remote("origin") | ||
| 891 | + tmp_dir = Path(tempfile.mkdtemp()) | ||
| 892 | + tmp_file = tmp_dir / "pwn" | ||
| 893 | + unsafe_options = [ | ||
| 894 | + { | ||
| 895 | + "receive-pack": f"touch {tmp_file}", | ||
| 896 | + "exec": f"touch {tmp_file}", | ||
| 897 | + } | ||
| 898 | + ] | ||
| 899 | + for unsafe_option in unsafe_options: | ||
| 900 | + # The options will be allowed, but the command will fail. | ||
| 901 | + with self.assertRaises(GitCommandError): | ||
| 902 | + remote.push(**unsafe_option, allow_unsafe_options=True) | ||
| 903 | + | ||
| 693 | 904 | ||
| 694 | 905 | class TestTimeouts(TestBase): | |
| 695 | 906 | @with_rw_repo("HEAD", bare=False) | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -1026,7 +1026,7 @@ def test_update_clone_multi_options_argument(self, rwdir): | |||
| 1026 | 1026 | ) | |
| 1027 | 1027 | ||
| 1028 | 1028 | # Act | |
| 1029 | - sm.update(init=True, clone_multi_options=["--config core.eol=true"]) | ||
| 1029 | + sm.update(init=True, clone_multi_options=["--config core.eol=true"], allow_unsafe_options=True) | ||
| 1030 | 1030 | ||
| 1031 | 1031 | # Assert | |
| 1032 | 1032 | sm_config = GitConfigParser(file_or_files=osp.join(parent.git_dir, "modules", sm_name, "config")) | |
@@ -1070,6 +1070,7 @@ def test_add_clone_multi_options_argument(self, rwdir): | |||
| 1070 | 1070 | sm_name, | |
| 1071 | 1071 | url=self._small_repo_url(), | |
| 1072 | 1072 | clone_multi_options=["--config core.eol=true"], | |
| 1073 | + allow_unsafe_options=True, | ||
| 1073 | 1074 | ) | |
| 1074 | 1075 | ||
| 1075 | 1076 | # Assert | |
| Back | FazBrowse Home | New Git URL |
0 commit comments