From 00d4f50da51609b7da55697b0f197d227f49388e Mon Sep 17 00:00:00 2001 From: Jeff Lenamon <85593689+lenamonj@users.noreply.github.com> Date: Sun, 6 Sep 2026 16:31:59 -0400 Subject: [PATCH] fix: handle short Maven group ids in the repository verifier A group id such as com.github or io.github, with the repository reported on github.com, raised IndexError in verify_domains and aborted the analysis. Fewer than three segments names no account to compare, so the method now returns UNKNOWN with reason git_ns_mismatch, the answer a wrong account gets. Closes #1463 Signed-off-by: Jeff Lenamon --- .../repo_verifier/repo_verifier_maven.py | 8 ++++ tests/repo_verifier/test_repo_verifier.py | 44 +++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/src/macaron/repo_verifier/repo_verifier_maven.py b/src/macaron/repo_verifier/repo_verifier_maven.py index b457887d4..4180724fe 100644 --- a/src/macaron/repo_verifier/repo_verifier_maven.py +++ b/src/macaron/repo_verifier/repo_verifier_maven.py @@ -114,6 +114,14 @@ def verify_domains_from_recognized_code_hosting_services(self) -> RepositoryVeri reported_account = parsed_url.path.strip("/").split("/")[0] group_parts = self.namespace.split(".") + # Fewer than three segments names no account to compare against. + if len(group_parts) < 3: + return RepositoryVerificationResult( + status=RepositoryVerificationStatus.UNKNOWN, + reason="git_ns_mismatch", + build_tool=self.build_tool, + ) + for platform in RECOGNIZED_CODE_HOSTING_SERVICES: # For artifacts from recognized code hosting services, check if the # organization name is the same in maven and the source repository. diff --git a/tests/repo_verifier/test_repo_verifier.py b/tests/repo_verifier/test_repo_verifier.py index 74f3cfe63..90b58be89 100644 --- a/tests/repo_verifier/test_repo_verifier.py +++ b/tests/repo_verifier/test_repo_verifier.py @@ -7,6 +7,7 @@ import pytest +from macaron.repo_verifier.repo_verifier_base import RepositoryVerificationStatus from macaron.repo_verifier.repo_verifier_gradle import RepoVerifierGradle from macaron.repo_verifier.repo_verifier_maven import RepoVerifierMaven from macaron.slsa_analyzer.build_tool.base_build_tool import BaseBuildTool @@ -140,3 +141,46 @@ def test_extract_group_id_from_pom( """ verifier = maven_repo_verifier(build_tools["maven"], str(mock_repo)) assert (verifier.extract_group_id_from_pom() is not None) == expected_result + + +@pytest.mark.parametrize( + ("namespace", "expected_status", "expected_reason"), + [ + # A three-segment namespace under a recognized code hosting service still + # matches, which is the behaviour the short-namespace guard must not change. + ("com.github.example", RepositoryVerificationStatus.PASSED, "git_ns_match"), + ("io.github.example", RepositoryVerificationStatus.PASSED, "git_ns_match"), + # Fewer than three segments cannot name an account, so the comparison has + # no answer to give and must report a mismatch rather than raise IndexError. + ("com.github", RepositoryVerificationStatus.UNKNOWN, "git_ns_mismatch"), + ("io.github", RepositoryVerificationStatus.UNKNOWN, "git_ns_mismatch"), + ("com", RepositoryVerificationStatus.UNKNOWN, "git_ns_mismatch"), + ("io", RepositoryVerificationStatus.UNKNOWN, "git_ns_mismatch"), + # A short namespace outside the io/com prefixes was already safe and stays so. + ("org.example", RepositoryVerificationStatus.UNKNOWN, "git_ns_mismatch"), + ], +) +def test_verify_domains_handles_short_namespaces( + build_tools: dict[str, BaseBuildTool], + namespace: str, + expected_status: RepositoryVerificationStatus, + expected_reason: str, +) -> None: + """A Maven namespace with fewer than three segments must not crash the repository check. + + The namespace reaches this code as ``parsed_purl.namespace`` straight from the analysis + target, and the analyzer wraps the call in no exception handler, so an IndexError here + aborts the whole analysis. + """ + verifier = RepoVerifierMaven( + namespace=namespace, + name="artifact", + version="1.0.0", + reported_repo_url="https://github.com/example/example", + reported_repo_fs="/nonexistent", + build_tool=build_tools["maven"], + provenance_repo_url=None, + ) + result = verifier.verify_domains_from_recognized_code_hosting_services() + assert result.status == expected_status + assert result.reason == expected_reason