Skip to content

Commit b65f0db

Browse files
authored
fix: block terminal prompts in find source (#918)
Signed-off-by: Ben Selwyn-Smith <benselwynsmith@googlemail.com>
1 parent ab0dd3e commit b65f0db

File tree

3 files changed

+67
-8
lines changed

3 files changed

+67
-8
lines changed

src/macaron/repo_finder/repo_finder.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
import os
3737
from urllib.parse import ParseResult, urlunparse
3838

39-
import git
4039
from packageurl import PackageURL
4140

4241
from macaron.config.defaults import defaults
@@ -47,7 +46,7 @@
4746
from macaron.repo_finder.repo_finder_deps_dev import DepsDevRepoFinder
4847
from macaron.repo_finder.repo_finder_java import JavaRepoFinder
4948
from macaron.repo_finder.repo_utils import generate_report, prepare_repo
50-
from macaron.slsa_analyzer.git_url import GIT_REPOS_DIR
49+
from macaron.slsa_analyzer.git_url import GIT_REPOS_DIR, list_remote_references
5150

5251
logger: logging.Logger = logging.getLogger(__name__)
5352

@@ -170,11 +169,11 @@ def find_source(purl_string: str, input_repo: str | None) -> bool:
170169

171170
# Disable other loggers for cleaner output.
172171
logging.getLogger("macaron.slsa_analyzer.analyzer").disabled = True
173-
logging.getLogger("macaron.slsa_analyzer.git_url").disabled = True
174172

175173
if defaults.getboolean("repofinder", "find_source_should_clone"):
176174
logger.debug("Preparing repo: %s", found_repo)
177175
repo_dir = os.path.join(global_config.output_path, GIT_REPOS_DIR)
176+
logging.getLogger("macaron.slsa_analyzer.git_url").disabled = True
178177
git_obj = prepare_repo(
179178
repo_dir,
180179
found_repo,
@@ -233,12 +232,10 @@ def get_tags_via_git_remote(repo: str) -> dict[str, str] | None:
233232
dict[str]
234233
A dictionary of tags mapped to their commits, or None if the operation failed..
235234
"""
236-
tags = {}
237-
try:
238-
tag_data = git.cmd.Git().ls_remote("--tags", repo)
239-
except git.exc.GitCommandError as error:
240-
logger.debug("Failed to retrieve tags: %s", error)
235+
tag_data = list_remote_references(["--tags"], repo)
236+
if not tag_data:
241237
return None
238+
tags = {}
242239

243240
for tag_line in tag_data.splitlines():
244241
tag_line = tag_line.strip()

src/macaron/slsa_analyzer/git_url.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from pydriller.git import Git
2020

2121
from macaron.config.defaults import defaults
22+
from macaron.config.global_config import global_config
2223
from macaron.environment_variables import get_patched_env
2324
from macaron.errors import CloneError
2425

@@ -376,6 +377,47 @@ def clone_remote_repo(clone_dir: str, url: str) -> Repo | None:
376377
return Repo(path=clone_dir)
377378

378379

380+
def list_remote_references(arguments: list[str], repo: str) -> str | None:
381+
"""Retrieve references from a remote repository using Git's ``ls-remote``.
382+
383+
Parameters
384+
----------
385+
arguments: list[str]
386+
The arguments to pass into the command.
387+
repo: str
388+
The repository to run the command on.
389+
390+
Returns
391+
-------
392+
str
393+
The result of the command.
394+
"""
395+
try:
396+
result = subprocess.run( # nosec B603
397+
args=["git", "ls-remote"] + arguments + [repo],
398+
capture_output=True,
399+
# By setting stdin to /dev/null and using a new session, we prevent all possible user input prompts.
400+
stdin=subprocess.DEVNULL,
401+
start_new_session=True,
402+
cwd=global_config.output_path,
403+
check=False,
404+
)
405+
except (subprocess.CalledProcessError, OSError):
406+
return None
407+
408+
if result.returncode != 0:
409+
error_string = result.stderr.decode("utf-8").strip()
410+
if error_string.startswith("fatal: could not read Username"):
411+
# Occurs when a repository cannot be accessed either because it does not exist, or it requires a login
412+
# that is blocked.
413+
logger.error("Could not access repository: %s", repo)
414+
else:
415+
logger.error("Failed to retrieve remote references from repo: %s", repo)
416+
return None
417+
418+
return result.stdout.decode("utf-8")
419+
420+
379421
def resolve_local_path(start_dir: str, local_path: str) -> str:
380422
"""Resolve the local path and check if it's within a directory.
381423
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Copyright (c) 2024 - 2024, Oracle and/or its affiliates. All rights reserved.
2+
# Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl/.
3+
4+
description: |
5+
Analyzing the find source command on a non-existent repository.
6+
7+
tags:
8+
- macaron-python-package
9+
- macaron-docker-image
10+
11+
steps:
12+
- name: Run macaron find source on private repository
13+
kind: find-source
14+
options:
15+
command_args:
16+
- -purl
17+
- pkg:maven/com.example/example@1.0.0
18+
- -rp
19+
- https://github.com/oracle/hopefully-this-repository-will-never-exist-0
20+
expect_fail: true

0 commit comments

Comments
 (0)