Skip to content

Commit

Permalink
fix: merge out of support entries when affected or fixed version in m…
Browse files Browse the repository at this point in the history
…ore recent release

Signed-off-by: Weston Steimel <[email protected]>
  • Loading branch information
westonsteimel committed Jul 27, 2023
1 parent fd7efe8 commit 25a8808
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 18 deletions.
35 changes: 21 additions & 14 deletions src/vunnel/providers/rhel/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ def _get_name_version(package):

return name, version

def _parse_affected_release(self, cve_id, content):
def _parse_affected_release(self, cve_id: str, content) -> list[FixedIn]:
fixed_ins = []
ars = content.get("affected_release", [])

Expand Down Expand Up @@ -563,9 +563,9 @@ def _parse_affected_release(self, cve_id, content):

return fixed_ins

def _parse_package_state(self, cve_id, content):
fixed_ins = []
out_of_support = [] # Track items out of support to be able to add them if others are affected
def _parse_package_state(self, cve_id: str, fixed: list[FixedIn], content) -> list[FixedIn]:
affected: list[FixedIn] = []
out_of_support: list[FixedIn] = [] # Track items out of support to be able to add them if others are affected
pss = content.get("package_state", [])

for item in pss:
Expand Down Expand Up @@ -595,7 +595,7 @@ def _parse_package_state(self, cve_id, content):

state = item.get("fix_state", None)
if state in ["Affected", "Fix deferred"]:
fixed_ins.append(
affected.append(
FixedIn(
platform=platform,
package=package_name,
Expand All @@ -605,7 +605,7 @@ def _parse_package_state(self, cve_id, content):
)
)
elif state in ["Will not fix"]:
fixed_ins.append(
affected.append(
FixedIn(
platform=platform,
package=package_name,
Expand Down Expand Up @@ -636,34 +636,41 @@ def _parse_package_state(self, cve_id, content):
except:
self.logger.exception(f"error parsing {cve_id} package state entity: {item}")

merged_fixed_ins = Parser._merge_out_of_support_affected(fixed_ins, out_of_support)
merged_fixed_ins = Parser._merge_out_of_support_affected(fixed, affected, out_of_support)
return merged_fixed_ins

@staticmethod
def _merge_out_of_support_affected(affected_fixed_ins: list[FixedIn], out_of_support: list[FixedIn]) -> list[FixedIn]:
if out_of_support and affected_fixed_ins:
merged = copy.deepcopy(affected_fixed_ins)
def _merge_out_of_support_affected(
fixed: list[FixedIn], affected: list[FixedIn], out_of_support: list[FixedIn]
) -> list[FixedIn]:
if not out_of_support:
return affected

if affected or fixed:
merged = copy.deepcopy(affected)

for oos in out_of_support:
for affected in affected_fixed_ins:
for r in affected + fixed:
# A newer release is impacted, so assume out-of-support version is as well
try:
if oos.package == affected.package and int(oos.platform) < int(affected.platform):
if oos.package == r.package and int(oos.platform) < int(r.platform):
merged.append(oos)
break
except ValueError:
# Be conservative if we cannot tell if it is <
merged.append(oos)
break
return merged
return affected_fixed_ins

return affected

def _parse_cve(self, cve_id, content):
# logger.debug('Parsing {}'.format(cve_id))

results = []
platform_artifacts = {}
fins = self._parse_affected_release(cve_id, content)
nfins = self._parse_package_state(cve_id, content)
nfins = self._parse_package_state(cve_id, fins, content)
platform_package_module_tuples = set()

if fins or nfins:
Expand Down
57 changes: 53 additions & 4 deletions tests/unit/providers/rhel/test_rhel.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,7 +444,7 @@ def test_parse_affected_releases(self, tmpdir, affected_releases, fixed_ins, moc

def test_parse_package_state(self, tmpdir, mock_cve):
driver = Parser(workspace=workspace.Workspace(tmpdir, "test", create=True))
results = driver._parse_package_state(mock_cve.get("name"), mock_cve)
results = driver._parse_package_state([], mock_cve.get("name"), mock_cve)

assert results and isinstance(results, list) and len(results) == 1
fixed_in = results[0]
Expand Down Expand Up @@ -512,9 +512,10 @@ def test_get_name_version(self, package, name, version):


@pytest.mark.parametrize(
"affected, out_of_support, expected",
"fixed, affected, out_of_support, expected",
[
(
[],
[
FixedIn(
module=None,
Expand Down Expand Up @@ -551,6 +552,7 @@ def test_get_name_version(self, package, name, version):
],
),
(
[],
[
FixedIn(
module=None,
Expand Down Expand Up @@ -580,6 +582,7 @@ def test_get_name_version(self, package, name, version):
],
),
(
[],
[
FixedIn(
module=None,
Expand All @@ -601,6 +604,7 @@ def test_get_name_version(self, package, name, version):
],
),
(
[],
[],
[
FixedIn(
Expand All @@ -614,6 +618,7 @@ def test_get_name_version(self, package, name, version):
[],
),
(
[],
[
FixedIn(
module=None,
Expand Down Expand Up @@ -642,10 +647,54 @@ def test_get_name_version(self, package, name, version):
),
],
),
(
[
FixedIn(
module=None,
platform="8",
package="foobar",
advisory=None,
version="1.2.3.4",
)
],
[],
[
FixedIn(
module=None,
platform="6",
package="foobar",
advisory=None,
version=None,
),
FixedIn(
module=None,
platform="7",
package="foobar",
advisory=None,
version=None,
),
],
[
FixedIn(
module=None,
platform="6",
package="foobar",
advisory=None,
version=None,
),
FixedIn(
module=None,
platform="7",
package="foobar",
advisory=None,
version=None,
),
],
),
],
)
def test_out_of_support(affected, out_of_support, expected):
assert Parser._merge_out_of_support_affected(affected, out_of_support) == expected
def test_out_of_support(fixed, affected, out_of_support, expected):
assert Parser._merge_out_of_support_affected(fixed, affected, out_of_support) == expected


@pytest.fixture
Expand Down

0 comments on commit 25a8808

Please sign in to comment.