Skip to content
Open
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
7 changes: 5 additions & 2 deletions dojo/tools/coverity_api/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,11 @@ def get_findings(self, file, test):

items = []
for issue in tree["viewContentsV1"]["rows"]:
# get only security findings
if issue.get("displayIssueKind") != "Security":
# get security findings and Quality RESOURCE_LEAK findings
if not (
issue.get("displayIssueKind") == "Security"
or (issue.get("displayIssueKind") == "Quality" and issue.get("checker") == "RESOURCE_LEAK")
):
continue

description_formated = "\n".join(
Expand Down
100 changes: 100 additions & 0 deletions unittests/scans/coverity_api/only_non_resource_leak_quality.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
{
"viewContentsV1": {
"offset": 0,
"totalRows": 3,
"columns": [
{"name": "cid", "label": "CID"},
{"name": "displayType", "label": "Type"},
{"name": "displayImpact", "label": "Impact"},
{"name": "status", "label": "Status"},
{"name": "firstDetected", "label": "First Detected"},
{"name": "owner", "label": "Owner"},
{"name": "classification", "label": "Classification"},
{"name": "severity", "label": "Severity"},
{"name": "action", "label": "Action"},
{"name": "displayComponent", "label": "Component"},
{"name": "displayCategory", "label": "Category"},
{"name": "displayFile", "label": "File"},
{"name": "displayFunction", "label": "Function"},
{"name": "displayIssueKind", "label": "Issue Kind"},
{"name": "lastDetected", "label": "Last Snapshot Date"},
{"name": "checker", "label": "Checker"},
{"name": "occurrenceCount", "label": "Count"},
{"name": "cwe", "label": "CWE"},
{"name": "lastTriaged", "label": "Last Triaged"},
{"name": "externalReference", "label": "External Reference"},
{"name": "lastDetectedTarget", "label": "Last Snapshot Target"}
],
"rows": [
{
"cid": 10001,
"displayType": "Dereference null return value",
"displayImpact": "Medium",
"status": "New",
"firstDetected": "03/23/21",
"owner": "Unassigned",
"classification": "Unclassified",
"severity": "Unspecified",
"action": "Undecided",
"displayComponent": "Other",
"displayCategory": "Null pointer dereferences",
"displayFile": "Aaaaaa/Bbbbbb/Cccccc/Dddddd.rs",
"displayFunction": "Eeeeee.Ffffff.Gggggg::Hhhhhh",
"displayIssueKind": "Quality",
"lastDetected": "04/07/21",
"checker": "NULL_RETURNS",
"occurrenceCount": 1,
"cwe": 476,
"lastTriaged": "",
"externalReference": "",
"lastDetectedTarget": ""
},
{
"cid": 10002,
"displayType": "Explicit null dereferenced",
"displayImpact": "Medium",
"status": "New",
"firstDetected": "03/23/21",
"owner": "Unassigned",
"classification": "Unclassified",
"severity": "Unspecified",
"action": "Undecided",
"displayComponent": "Other",
"displayCategory": "Null pointer dereferences",
"displayFile": "Iiiiii/Jjjjjj/Kkkkkk/Llllll.rs",
"displayFunction": "Mmmmmm.Nnnnnn.Oooooo::Pppppp",
"displayIssueKind": "Quality",
"lastDetected": "04/07/21",
"checker": "FORWARD_NULL",
"occurrenceCount": 2,
"cwe": 476,
"lastTriaged": "",
"externalReference": "",
"lastDetectedTarget": ""
},
{
"cid": 10003,
"displayType": "Dereference null return (stat)",
"displayImpact": "Medium",
"status": "New",
"firstDetected": "03/23/21",
"owner": "Unassigned",
"classification": "Unclassified",
"severity": "Unspecified",
"action": "Undecided",
"displayComponent": "Other",
"displayCategory": "Null pointer dereferences",
"displayFile": "Qqqqqq/Rrrrrr/Ssssss/Tttttt.rs",
"displayFunction": "Uuuuuu.Vvvvvv.Wwwwww::Xxxxxx",
"displayIssueKind": "Quality",
"lastDetected": "04/07/21",
"checker": "NULL_RETURNS",
"occurrenceCount": 1,
"cwe": 476,
"lastTriaged": "",
"externalReference": "",
"lastDetectedTarget": ""
}
]
}
}
48 changes: 34 additions & 14 deletions unittests/tools/test_coverity_api_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ def test_parse_no_findings(self):
self.assertEqual(0, len(findings))

def test_parse_only_quality(self):
"""This report only have quality findings"""
with (get_unit_tests_scans_path("coverity_api") / "only_quality.json").open(encoding="utf-8") as testfile:
"""Non-RESOURCE_LEAK quality findings are excluded"""
with (get_unit_tests_scans_path("coverity_api") / "only_non_resource_leak_quality.json").open(encoding="utf-8") as testfile:
parser = CoverityApiParser()
findings = parser.get_findings(testfile, Test())
self.assertEqual(0, len(findings))
Expand All @@ -30,11 +30,21 @@ def test_parse_some_findings(self):
parser = CoverityApiParser()
findings = parser.get_findings(testfile, Test())
self.assertIsInstance(findings, list)
self.assertEqual(1, len(findings))
self.assertEqual(6, len(findings))
with self.subTest(i=0):
finding = findings[0]
finding = findings[0] # first RESOURCE_LEAK finding
self.assertTrue(finding.active)
self.assertFalse(finding.verified) # this one is marked as new ("status": "New")
self.assertFalse(finding.verified)
self.assertEqual("Resource leak", finding.title)
self.assertEqual("High", finding.severity)
self.assertEqual(404, finding.cwe)
self.assertEqual("Wdkrtgthhl/Llwfzgphzw/Fashvkaxzx/Okkfacqsxw.rs", finding.file_path)
self.assertEqual(datetime.date(2021, 3, 23), finding.date)
self.assertEqual(22480, finding.unique_id_from_tool)
with self.subTest(i=4):
finding = findings[4] # security finding
self.assertTrue(finding.active)
self.assertFalse(finding.verified)
self.assertEqual("Risky cryptographic hashing function", finding.title)
self.assertEqual("Medium", finding.severity)
self.assertEqual(328, finding.cwe)
Expand All @@ -47,9 +57,9 @@ def test_parse_few_findings_triaged_as_bug(self):
parser = CoverityApiParser()
findings = parser.get_findings(testfile, Test())
self.assertIsInstance(findings, list)
self.assertEqual(1, len(findings))
with self.subTest(i=0):
finding = findings[0]
self.assertEqual(13, len(findings))
with self.subTest(i=1):
finding = findings[1] # security finding (triaged as bug)
self.assertTrue(finding.active)
self.assertTrue(finding.verified)
self.assertEqual("HTTP header injection", finding.title)
Expand All @@ -64,9 +74,19 @@ def test_parse_some_findings_mitigated(self):
parser = CoverityApiParser()
findings = parser.get_findings(testfile, Test())
self.assertIsInstance(findings, list)
self.assertEqual(20, len(findings))
self.assertEqual(25, len(findings))
with self.subTest(i=0):
finding = findings[0] # this one is dismissed as a false positive
finding = findings[0] # RESOURCE_LEAK finding (active, status New)
self.assertTrue(finding.active)
self.assertFalse(finding.verified)
self.assertEqual("Resource leak", finding.title)
self.assertEqual("High", finding.severity)
self.assertEqual(404, finding.cwe)
self.assertEqual("Vzfkposilb/Ejgmugyeam/Ekcbsjzuiq/Isjhjabnfe.rs", finding.file_path)
self.assertEqual(datetime.date(2021, 3, 31), finding.date)
self.assertEqual(22496, finding.unique_id_from_tool)
with self.subTest(i=2):
finding = findings[2] # this one is dismissed as a false positive
self.assertFalse(finding.active)
self.assertTrue(finding.verified)
self.assertTrue(finding.false_p)
Expand All @@ -76,8 +96,8 @@ def test_parse_some_findings_mitigated(self):
self.assertEqual("Pfozpmtueo/Vtoqmbvmzf/Noxacjclcz/Aymctwefbi.rs", finding.file_path)
self.assertEqual(datetime.date(2021, 3, 26), finding.date)
self.assertEqual(22486, finding.unique_id_from_tool)
with self.subTest(i=10):
finding = findings[10]
with self.subTest(i=12):
finding = findings[12]
self.assertFalse(finding.active)
self.assertTrue(finding.verified)
self.assertEqual("Use of hard-coded password", finding.title)
Expand All @@ -86,8 +106,8 @@ def test_parse_some_findings_mitigated(self):
self.assertEqual("Hvsilgzkwz/Lhmxrchybr/Edcoanzncg/Oowieyoxvn.rs", finding.file_path)
self.assertEqual(datetime.date(2021, 3, 15), finding.date)
self.assertEqual(22421, finding.unique_id_from_tool)
with self.subTest(i=19):
finding = findings[19]
with self.subTest(i=23):
finding = findings[23]
self.assertFalse(finding.active)
self.assertTrue(finding.verified)
self.assertEqual("Cross-site scripting", finding.title)
Expand Down
Loading