Submodule tests · gitpython-developers/GitPython@9dc4392

@@ -3,6 +3,8 @@

33

# the BSD License: http://www.opensource.org/licenses/bsd-license.php

44

import os

55

import shutil

6+

import tempfile

7+

from pathlib import Path

68

import sys

79

from unittest import skipIf

810

@@ -12,7 +14,13 @@

1214

from git.cmd import Git

1315

from git.compat import is_win

1416

from git.config import GitConfigParser, cp

15-

from git.exc import InvalidGitRepositoryError, RepositoryDirtyError

17+

from git.exc import (

18+

GitCommandError,

19+

InvalidGitRepositoryError,

20+

RepositoryDirtyError,

21+

UnsafeOptionError,

22+

UnsafeProtocolError,

23+

)

1624

from git.objects.submodule.base import Submodule

1725

from git.objects.submodule.root import RootModule, RootUpdateProgress

1826

from git.repo.fun import find_submodule_git_dir, touch

@@ -1090,3 +1098,109 @@ def test_add_no_clone_multi_options_argument(self, rwdir):

10901098

sm_config = GitConfigParser(file_or_files=osp.join(parent.git_dir, "modules", sm_name, "config"))

10911099

with self.assertRaises(cp.NoOptionError):

10921100

sm_config.get_value("core", "eol")

1101+1102+

@with_rw_repo("HEAD")

1103+

def test_submodule_add_unsafe_url(self, rw_repo):

1104+

urls = [

1105+

"ext::sh -c touch% /tmp/pwn",

1106+

"fd::/foo",

1107+

]

1108+

for url in urls:

1109+

with self.assertRaises(UnsafeProtocolError):

1110+

Submodule.add(rw_repo, "new", "new", url)

1111+1112+

@with_rw_repo("HEAD")

1113+

def test_submodule_add_unsafe_url_allowed(self, rw_repo):

1114+

urls = [

1115+

"ext::sh -c touch% /tmp/pwn",

1116+

"fd::/foo",

1117+

]

1118+

for url in urls:

1119+

# The URL will be allowed into the command, but the command will

1120+

# fail since we don't have that protocol enabled in the Git config file.

1121+

with self.assertRaises(GitCommandError):

1122+

Submodule.add(rw_repo, "new", "new", url, allow_unsafe_protocols=True)

1123+1124+

@with_rw_repo("HEAD")

1125+

def test_submodule_add_unsafe_options(self, rw_repo):

1126+

tmp_dir = Path(tempfile.mkdtemp())

1127+

tmp_file = tmp_dir / "pwn"

1128+

unsafe_options = [

1129+

f"--upload-pack='touch {tmp_file}'",

1130+

f"-u 'touch {tmp_file}'",

1131+

"--config=protocol.ext.allow=always",

1132+

"-c protocol.ext.allow=always",

1133+

]

1134+

for unsafe_option in unsafe_options:

1135+

with self.assertRaises(UnsafeOptionError):

1136+

Submodule.add(rw_repo, "new", "new", str(tmp_dir), clone_multi_options=[unsafe_option])

1137+1138+

@with_rw_repo("HEAD")

1139+

def test_submodule_add_unsafe_options_allowed(self, rw_repo):

1140+

tmp_dir = Path(tempfile.mkdtemp())

1141+

tmp_file = tmp_dir / "pwn"

1142+

unsafe_options = [

1143+

f"--upload-pack='touch {tmp_file}'",

1144+

f"-u 'touch {tmp_file}'",

1145+

"--config=protocol.ext.allow=always",

1146+

"-c protocol.ext.allow=always",

1147+

]

1148+

for unsafe_option in unsafe_options:

1149+

with self.assertRaises(GitCommandError):

1150+

Submodule.add(

1151+

rw_repo, "new", "new", str(tmp_dir), clone_multi_options=[unsafe_option], allow_unsafe_options=True

1152+

)

1153+1154+

@with_rw_repo("HEAD")

1155+

def test_submodule_update_unsafe_url(self, rw_repo):

1156+

urls = [

1157+

"ext::sh -c touch% /tmp/pwn",

1158+

"fd::/foo",

1159+

]

1160+

for url in urls:

1161+

submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=url)

1162+

with self.assertRaises(UnsafeProtocolError):

1163+

submodule.update()

1164+1165+

@with_rw_repo("HEAD")

1166+

def test_submodule_update_unsafe_url_allowed(self, rw_repo):

1167+

urls = [

1168+

"ext::sh -c touch% /tmp/pwn",

1169+

"fd::/foo",

1170+

]

1171+

for url in urls:

1172+

submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=url)

1173+

# The URL will be allowed into the command, but the command will

1174+

# fail since we don't have that protocol enabled in the Git config file.

1175+

with self.assertRaises(GitCommandError):

1176+

submodule.update(allow_unsafe_protocols=True)

1177+1178+

@with_rw_repo("HEAD")

1179+

def test_submodule_update_unsafe_options(self, rw_repo):

1180+

tmp_dir = Path(tempfile.mkdtemp())

1181+

tmp_file = tmp_dir / "pwn"

1182+

unsafe_options = [

1183+

f"--upload-pack='touch {tmp_file}'",

1184+

f"-u 'touch {tmp_file}'",

1185+

"--config=protocol.ext.allow=always",

1186+

"-c protocol.ext.allow=always",

1187+

]

1188+

submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=str(tmp_dir))

1189+

for unsafe_option in unsafe_options:

1190+

with self.assertRaises(UnsafeOptionError):

1191+

submodule.update(clone_multi_options=[unsafe_option])

1192+1193+

@with_rw_repo("HEAD")

1194+

def test_submodule_update_unsafe_options_allowed(self, rw_repo):

1195+

tmp_dir = Path(tempfile.mkdtemp())

1196+

tmp_file = tmp_dir / "pwn"

1197+

unsafe_options = [

1198+

f"--upload-pack='touch {tmp_file}'",

1199+

f"-u 'touch {tmp_file}'",

1200+

"--config=protocol.ext.allow=always",

1201+

"-c protocol.ext.allow=always",

1202+

]

1203+

submodule = Submodule(rw_repo, b"\0" * 20, name="new", path="new", url=str(tmp_dir))

1204+

for unsafe_option in unsafe_options:

1205+

with self.assertRaises(GitCommandError):

1206+

submodule.update(clone_multi_options=[unsafe_option], allow_unsafe_options=True)