Skip to content

Commit 1c48b13

Browse files
committed
Add OVAL parsing test #1079
Reference: #1079 Signed-off-by: John M. Horan <johnmhoran@gmail.com>
1 parent cc29340 commit 1c48b13

3 files changed

Lines changed: 66 additions & 15 deletions

File tree

vulnerabilities/importer.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -516,16 +516,18 @@ def get_data_from_xml_doc(
516516
oval_doc = oval_parsed_data.oval_document
517517
timestamp = oval_doc.getGenerator().getTimestamp()
518518

519-
print("\noval_parsed_data = {}\n".format(oval_parsed_data))
520-
print("\nraw_data = {}\n".format(raw_data))
519+
print("\n== Run OvalImporter() get_data_from_xml_doc() ==\n")
520+
521+
# print("\noval_parsed_data = {}\n".format(oval_parsed_data))
522+
print("\n==> raw_data = {}\n".format(raw_data))
521523

522524
# convert definition_data to Advisory objects
523525
for definition_data in raw_data:
524-
print("\ndefinition_data = {}\n".format(definition_data))
526+
print("\n==> definition_data = {}\n".format(definition_data))
525527
# These fields are definition level, i.e common for all elements
526528
# connected/linked to an OvalDefinition
527529

528-
# TODO: 2023-01-24 Tuesday 22:34:20. Is this where we'd loop through the list of CVEs/aliases?
530+
# NOTE: This is where we loop through the list of CVEs/aliases.
529531

530532
vuln_id_list = definition_data["vuln_id"]
531533

@@ -545,9 +547,13 @@ def get_data_from_xml_doc(
545547
for url in definition_data["reference_urls"]
546548
]
547549
affected_packages = []
548-
print('\ndefinition_data["test_data"] = {}\n'.format(definition_data["test_data"]))
550+
print(
551+
'\n==> definition_data["test_data"] = {}\n'.format(definition_data["test_data"])
552+
)
549553
for test_data in definition_data["test_data"]:
550-
print("\ntest_data['package_list'] = {}\n".format(test_data["package_list"]))
554+
print(
555+
"\n==> test_data['package_list'] = {}\n".format(test_data["package_list"])
556+
)
551557
for package_name in test_data["package_list"]:
552558
affected_version_range = test_data["version_ranges"]
553559
vrc = RANGE_CLASS_BY_SCHEMES[pkg_metadata["type"]]
@@ -567,7 +573,7 @@ def get_data_from_xml_doc(
567573
affected_version_range=affected_version_range,
568574
)
569575
)
570-
print("affected_packages = {}".format(affected_packages))
576+
print("==> affected_packages = {}\n".format(affected_packages))
571577
date_published = dateparser.parse(timestamp)
572578
if not date_published.tzinfo:
573579
date_published = date_published.replace(tzinfo=pytz.UTC)

vulnerabilities/oval_parser.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,15 @@ def get_data(self) -> List[Dict]:
5353

5454
definition_data["severity"] = self.get_severity_from_definition(definition)
5555
print("\nlen(matching_tests) = {}\n".format(len(matching_tests)))
56-
print("\nmatching_tests = {}\n".format(matching_tests))
56+
# print("\nmatching_tests = {}\n".format(matching_tests))
5757
for test in matching_tests:
58-
print("\ntest = {}\n".format(test))
58+
# print("\ntest = {}\n".format(test))
59+
# print("\ntest.element = {}\n".format(test.element))
5960
test_obj, test_state = self.get_object_state_of_test(test)
6061
if not test_obj or not test_state:
6162
continue
6263
test_data = {"package_list": []}
63-
print("\ntest_obj = {}\n".format(test_obj))
64+
# print("\ntest_obj = {}\n".format(test_obj))
6465
test_data["package_list"].extend(self.get_pkgs_from_obj(test_obj))
6566
print(
6667
"\nself.get_pkgs_from_obj(test_obj) = {}\n".format(
@@ -101,7 +102,9 @@ def get_tests_of_definition(self, definition: OvalDefinition) -> List[OvalTest]:
101102
break
102103
if valid_test:
103104
matching_tests.append(self.oval_document.getElementByID(ref))
104-
print(matching_tests)
105+
print("\nThese are matching_tests: {}".format(matching_tests))
106+
for mt in matching_tests:
107+
print("mt = {}".format(mt.element))
105108

106109
return list(set(matching_tests))
107110

vulnerabilities/tests/test_suse_oval.py

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,18 @@
1111
import xml.etree.ElementTree as ET
1212

1313
from vulnerabilities.importers.suse_oval import SuseOvalImporter
14+
from vulnerabilities.oval_parser import OvalParser
1415
from vulnerabilities.tests import util_tests
1516

1617
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
1718
TEST_DATA = os.path.join(BASE_DIR, "test_data/suse_oval")
1819

1920

20-
# TODO: How can we test a .gz file? This would be like running one .gz through _fetch().
21+
# TODO: How can we test a .gz file?
2122

2223

23-
# TODO: How are the packages identified?
24+
# TODO: A question for all these tests and the code more generally: how are the packages
25+
# associated with definitions/aliases/CVEs?
2426
def test_suse_oval_importer_leap_micro_5_3():
2527
importer = SuseOvalImporter()
2628
advisories = importer.get_data_from_xml_doc(
@@ -33,7 +35,9 @@ def test_suse_oval_importer_leap_micro_5_3():
3335
)
3436

3537

36-
# TODO: How do we handle multiple CVEs in a single section? Is this only in patch files?
38+
# TODO: All 80 affected packages (1 for each alias) in the expected JSON are `openSUSE-release`.
39+
# What about the other 54 or so packages identified in the XML file's `object` element?
40+
# See lines 1668-1834.
3741
def test_suse_oval_importer_leap_micro_5_3_patch():
3842
importer = SuseOvalImporter()
3943
advisories = importer.get_data_from_xml_doc(
@@ -46,7 +50,8 @@ def test_suse_oval_importer_leap_micro_5_3_patch():
4650
)
4751

4852

49-
# TODO: This creates 2 identical packages -- why?
53+
# TODO: This creates an 'opera' package in the expected JSON. Should it also create a
54+
# 'openSUSE-release' package? See line 64 of the XML file.
5055
def test_suse_oval_importer_CVE_2008_5679():
5156
importer = SuseOvalImporter()
5257
advisories = importer.get_data_from_xml_doc(
@@ -57,3 +62,40 @@ def test_suse_oval_importer_CVE_2008_5679():
5762
util_tests.check_results_against_json(
5863
[advisory.to_dict() for advisory in advisories], expected_file
5964
)
65+
66+
67+
# Explore parsing inspired by /vulnerablecode/vulnerabilities/tests/test_suse.py
68+
def test_suse_oval_parse_CVE_2008_5679():
69+
# xml_doc = ET.parse(os.path.join(TEST_DATA, "org.opensuse.CVE-2008-5679.xml"))
70+
xml_doc = ET.parse(os.path.join(TEST_DATA, "opensuse.leap.micro.5.3.xml"))
71+
translations = {"less than": "<", "equals": "=", "greater than or equal": ">="}
72+
73+
parsed_oval = OvalParser(translations, xml_doc)
74+
print("\n\ntype(parsed_oval) = {}\n".format(type(parsed_oval)))
75+
76+
print("parsed_oval.all_definitions = {}".format(parsed_oval.all_definitions))
77+
print("len(parsed_oval.all_definitions) = {}".format(len(parsed_oval.all_definitions)))
78+
79+
definition_1 = parsed_oval.all_definitions[0]
80+
print("\ndefinition_1 = {}".format(definition_1))
81+
print("definition_1.getId() = {}\n".format(definition_1.getId()))
82+
83+
# if parsed_oval.all_definitions[1]:
84+
# definition_2 = parsed_oval.all_definitions[1]
85+
# print("definition_2 = {}".format(definition_2))
86+
# print("definition_2.getId() = {}".format(definition_2.getId()))
87+
88+
# For each definition, we can get tests for that definition
89+
# i.getId() for i in self.parsed_oval.get_tests_of_definition(self.definition_1)
90+
test_id_1 = {i.getId() for i in parsed_oval.get_tests_of_definition(definition_1)}
91+
print("\ntest_id_1 = {}\n".format(test_id_1))
92+
93+
try:
94+
definition_2 = parsed_oval.all_definitions[1]
95+
print("definition_2 = {}".format(definition_2))
96+
print("definition_2.getId() = {}".format(definition_2.getId()))
97+
98+
test_id_2 = {i.getId() for i in parsed_oval.get_tests_of_definition(definition_2)}
99+
print("\ntest_id_2 = {}\n".format(test_id_2))
100+
except IndexError:
101+
pass

0 commit comments

Comments
 (0)