support/scripts/pkg-stats: adapt to NVD v2 json format

Commit 22b6945552 (support/scripts/cve.py: switch from NVD to FKIE for
the JSON files) missed the fact that the layout of the FKIE data files
are different from the original NVD ones. They are formatted according
to the NVD v2 API.

Most differences are relatively trivial fields renaming, and those are
easily spotted in this patch.

There is however one key difference in the layout of the configurations.
Where the NVD had "configurations" as an object with a "nodes" key, the
FKIE has a "configurations" as a list of objects with a single "nodes"
key; i.e. it is one-level deeper.

Signed-off-by: Yann E. MORIN <yann.morin.1998@free.fr>
Cc: Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>
Signed-off-by: Arnout Vandecappelle <arnout@mind.be>
This commit is contained in:
Yann E. MORIN 2024-02-25 23:05:36 +01:00 committed by Arnout Vandecappelle
parent f71d9f49e5
commit 54f8d97c91

View File

@ -128,7 +128,7 @@ class CVE:
filename = CVE.download_nvd_year(nvd_dir, year)
try:
uncompressed = subprocess.check_output(["xz", "-d", "-c", filename])
content = ijson.items(uncompressed, 'CVE_Items.item')
content = ijson.items(uncompressed, 'cve_items.item')
except: # noqa: E722
print("ERROR: cannot read %s. Please remove the file then rerun this script" % filename)
raise
@ -155,11 +155,11 @@ class CVE:
for parsed_node in self.parse_node(child):
yield parsed_node
for cpe in node.get('cpe_match', ()):
for cpe in node.get('cpeMatch', ()):
if not cpe['vulnerable']:
return
product = cpe_product(cpe['cpe23Uri'])
version = cpe_version(cpe['cpe23Uri'])
product = cpe_product(cpe['criteria'])
version = cpe_version(cpe['criteria'])
# ignore when product is '-', which means N/A
if product == '-':
return
@ -191,7 +191,7 @@ class CVE:
v_end = cpe['versionEndExcluding']
yield {
'id': cpe['cpe23Uri'],
'id': cpe['criteria'],
'v_start': v_start,
'op_start': op_start,
'v_end': v_end,
@ -199,14 +199,15 @@ class CVE:
}
def each_cpe(self):
for node in self.nvd_cve['configurations']['nodes']:
for cpe in self.parse_node(node):
yield cpe
for nodes in self.nvd_cve.get('configurations', []):
for node in nodes['nodes']:
for cpe in self.parse_node(node):
yield cpe
@property
def identifier(self):
"""The CVE unique identifier"""
return self.nvd_cve['cve']['CVE_data_meta']['ID']
return self.nvd_cve['id']
@property
def affected_products(self):