Skip to content

Commit 882593c

Browse files
committed
sync(fix[update_repo]): Capture obtain() failures in SyncResult
why: CommandError from obtain() propagated uncaught, bypassing the structured SyncResult error reporting that all other sync steps use. what: - Wrap obtain() in try/except in GitSync.update_repo() - Wrap obtain() in try/except in HgSync.update_repo() - Wrap obtain() in try/except in SvnSync.update_repo() - Update command injection test to check SyncResult instead of raised exception
1 parent f7554ef commit 882593c

4 files changed

Lines changed: 23 additions & 5 deletions

File tree

src/libvcs/sync/git.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,12 @@ def update_repo(
398398
self.ensure_dir()
399399

400400
if not pathlib.Path(self.path / ".git").is_dir():
401-
self.obtain()
401+
try:
402+
self.obtain()
403+
except exc.CommandError as e:
404+
self.log.exception("Failed to obtain repository")
405+
result.add_error("obtain", str(e), exception=e)
406+
return result
402407
return self.update_repo(set_remotes=set_remotes)
403408

404409
if set_remotes:

src/libvcs/sync/hg.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,12 @@ def update_repo(self, *args: t.Any, **kwargs: t.Any) -> SyncResult:
7575
"""
7676
result = SyncResult()
7777
if not pathlib.Path(self.path / ".hg").exists():
78-
self.obtain()
78+
try:
79+
self.obtain()
80+
except exc.CommandError as e:
81+
self.log.exception("Failed to obtain repository")
82+
result.add_error("obtain", str(e), exception=e)
83+
return result
7984
return self.update_repo()
8085
else:
8186
try:

src/libvcs/sync/svn.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,12 @@ def update_repo(
178178
except exc.CommandError as e:
179179
result.add_error("checkout", str(e), exception=e)
180180
else:
181-
self.obtain()
181+
try:
182+
self.obtain()
183+
except exc.CommandError as e:
184+
self.log.exception("Failed to obtain repository")
185+
result.add_error("obtain", str(e), exception=e)
186+
return result
182187
return self.update_repo()
183188
return result
184189

tests/sync/test_hg.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,12 @@ def test_vulnerability_2022_03_12_command_injection(
9595
vcs="hg",
9696
path="./",
9797
)
98-
with pytest.raises(exc.CommandError):
99-
mercurial_repo.update_repo()
98+
result = mercurial_repo.update_repo()
10099

100+
assert not result.ok, "update_repo() should report failure for malicious URL"
101+
assert any(e.step == "obtain" for e in result.errors), (
102+
"Error should be recorded under 'obtain' step"
103+
)
101104
assert not pathlib.Path(
102105
random_dir / "HELLO",
103106
).exists(), "Prevent command injection in hg aliases"

0 commit comments

Comments
 (0)