Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions src/yardstick/label.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,10 @@ def find_labels_for_match( # noqa: PLR0913, PLR0912, C901


def has_overlapping_vulnerability_id(label_entry: LabelEntry, match: Match) -> bool:
left_ids = {label_entry.vulnerability_id, label_entry.effective_cve}
right_ids = {match.vulnerability.id, match.vulnerability.cve_id}

if "" in left_ids:
left_ids.remove("")

if "" in right_ids:
right_ids.remove("")
# drop None and "" so a missing effective_cve on the label and a missing
# cve_id on the match don't intersect as a shared "token"
left_ids = {label_entry.vulnerability_id, label_entry.effective_cve} - {None, ""}
right_ids = {match.vulnerability.id, match.vulnerability.cve_id} - {None, ""}

return bool(left_ids & right_ids)

Expand Down
50 changes: 50 additions & 0 deletions tests/unit/test_label.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from yardstick.label import (
_contains_as_value,
find_labels_for_match,
has_overlapping_vulnerability_id,
merge_label_entries,
)

Expand Down Expand Up @@ -192,6 +193,17 @@ def label_entries(self):
),
["5"],
),
# case: match on a non-CVE vuln id (e.g. GHSA) must not pull in labels
# for *different* non-CVE vuln ids on the same package just because
# both sides have no effective_cve / cve_id
(
"my/image:latest",
artifact.Match(
vulnerability=artifact.Vulnerability(id="GHSA-xxxx-yyyy-zzzz"),
package=artifact.Package(name="package", version="1.0"),
),
[],
),
],
)
def test_find_labels_for_match(
Expand All @@ -205,6 +217,44 @@ def test_find_labels_for_match(
assert expected_label_ids == ids


class TestHasOverlappingVulnerabilityID:
@pytest.mark.parametrize(
("label_vuln_id", "label_effective_cve", "match_vuln_id", "match_cve_id", "expected"),
[
# same CVE on both sides
("CVE-2020-0001", None, "CVE-2020-0001", "CVE-2020-0001", True),
# same GHSA on both sides (no CVEs known)
("GHSA-aaaa-bbbb-cccc", None, "GHSA-aaaa-bbbb-cccc", None, True),
# GHSA on the label aliases to a CVE that the match also carries
("GHSA-aaaa-bbbb-cccc", "CVE-2020-0001", "CVE-2020-0001", "CVE-2020-0001", True),
# GHSA on the match aliases to a CVE that the label also carries
("CVE-2020-0001", None, "GHSA-aaaa-bbbb-cccc", "CVE-2020-0001", True),
# different non-CVE ids with no CVE aliases on either side must NOT overlap
# (regression: previously both sides carried None and set-intersected on it)
("GHSA-aaaa-bbbb-cccc", None, "GHSA-xxxx-yyyy-zzzz", None, False),
# same guard, but with empty strings instead of None
("GHSA-aaaa-bbbb-cccc", "", "GHSA-xxxx-yyyy-zzzz", "", False),
# completely disjoint CVE ids
("CVE-2020-0001", None, "CVE-2020-0002", "CVE-2020-0002", False),
],
)
def test_overlap(self, label_vuln_id, label_effective_cve, match_vuln_id, match_cve_id, expected):
label_entry = artifact.LabelEntry(
label=artifact.Label.FalsePositive,
vulnerability_id=label_vuln_id,
effective_cve=label_effective_cve,
package=artifact.Package(name="package", version="1.0"),
source="manual",
user="somebody",
ID="x",
)
match = artifact.Match(
vulnerability=artifact.Vulnerability(id=match_vuln_id, cve_id=match_cve_id),
package=artifact.Package(name="package", version="1.0"),
)
assert has_overlapping_vulnerability_id(label_entry, match) is expected


class TestMergeLabelEntries:
@pytest.fixture()
def existing_label_entries(self):
Expand Down