blob: 71d8fe502c4d55cfd2e503a7ee3219770b121698 [file]
#!/usr/bin/env python3
#
# Compare two CVE reports and output a formatted rST CVE array (for release
# notes).
#
# We consider that a CVE is "fixed" if either:
# - the CVE status changes from Unpatched to Patched in the new report.
# - the Unpatched CVE is unlisted in the new report.
#
# Reports can be found here: https://valkyrie.yocto.io/pub/non-release/?type=metrics
import sys
import json
json_prev_path = sys.argv[1]
json_next_path = sys.argv[2]
data_prev, data_next = None, None
with open(json_prev_path, 'r') as fd_prev, open(json_prev_path, 'r') as fd_next:
data_prev = json.load(fd_prev)["package"]
data_next = json.load(fd_next)["package"]
patched_cves = {}
for pkg_prev in data_prev:
pkg_name = pkg_prev["name"]
pkg_next = None
for p in data_next:
if p["name"] == pkg_name:
pkg_next = p
break
if pkg_next is not None:
prev_unpatched = [cve["id"] for cve in pkg_prev["issue"] if cve["status"] == "Unpatched"]
# next_patched = set([cve["id"] for cve in pkg_next["issue"] if cve["status"] == "Patched"])
pkg_patched_cves = []
for cve in prev_unpatched:
if cve in pkg_next["issue"] and pkg_next["issue"][cve]["status"] == "Patched":
pkg_patched_cves.append(cve)
if cve not in pkg_next["issue"]:
pkg_patched_cves.append(cve)
if pkg_patched_cves:
patched_cves[pkg_name] = sorted(pkg_patched_cves, key=lambda cve: (int(cve.split('-')[1]), int(cve.split('-')[2])))
if not patched_cves:
print("No patched CVEs found")
exit(0)
# Remove -native duplicates
for pkg in list(patched_cves):
if pkg.endswith("-native") and pkg[:-len("-native")] in patched_cves:
patched_cves.pop(pkg)
print(""".. list-table::
:widths: 30 70
:header-rows: 1
* - Recipe
- CVE IDs""")
for pkg in sorted(patched_cves.keys()):
cves_rst = ", ".join([f":cve_nist:`{c[4:]}`" for c in patched_cves[pkg]])
print(f" * - ``{pkg}``")
print(f" - {cves_rst}")