mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-04-14 16:50:04 +00:00
fix(sdk): improve SARIF location builder type safety and line validation
- Return Optional[dict] instead of empty dict from _build_location - Guard against zero line numbers (SARIF spec requires >= 1) - Add test for zero line number edge case
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
from json import dump
|
||||
from typing import Optional
|
||||
|
||||
from prowler.config.config import prowler_version
|
||||
from prowler.lib.logger import logger
|
||||
@@ -92,7 +93,7 @@ class SARIF(Output):
|
||||
}
|
||||
|
||||
location = self._build_location(finding)
|
||||
if location:
|
||||
if location is not None:
|
||||
result["locations"] = [location]
|
||||
|
||||
results.append(result)
|
||||
@@ -134,14 +135,17 @@ class SARIF(Output):
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _build_location(finding: Finding) -> dict:
|
||||
def _build_location(finding: Finding) -> Optional[dict]:
|
||||
"""Build a SARIF physicalLocation from a Finding.
|
||||
|
||||
Uses resource_name as the artifact URI and resource_line_range
|
||||
(stored in finding.raw for IaC findings) for line range info.
|
||||
|
||||
Returns:
|
||||
A SARIF location dict, or None if resource_name is empty.
|
||||
"""
|
||||
if not finding.resource_name:
|
||||
return {}
|
||||
return None
|
||||
|
||||
location = {
|
||||
"physicalLocation": {
|
||||
@@ -157,10 +161,11 @@ class SARIF(Output):
|
||||
try:
|
||||
start_line = int(parts[0])
|
||||
end_line = int(parts[1])
|
||||
location["physicalLocation"]["region"] = {
|
||||
"startLine": start_line,
|
||||
"endLine": end_line,
|
||||
}
|
||||
if start_line >= 1 and end_line >= 1:
|
||||
location["physicalLocation"]["region"] = {
|
||||
"startLine": start_line,
|
||||
"endLine": end_line,
|
||||
}
|
||||
except (ValueError, IndexError):
|
||||
pass # Malformed line range — skip region, keep location
|
||||
|
||||
|
||||
@@ -288,6 +288,18 @@ class TestSARIF:
|
||||
]
|
||||
assert "region" not in location
|
||||
|
||||
def test_location_with_zero_line_numbers(self):
|
||||
finding = generate_finding_output(
|
||||
status="FAIL",
|
||||
resource_name="main.tf",
|
||||
)
|
||||
finding.raw = {"resource_line_range": "0:0"}
|
||||
sarif = SARIF(findings=[finding], file_path=None)
|
||||
location = sarif.data[0]["runs"][0]["results"][0]["locations"][0][
|
||||
"physicalLocation"
|
||||
]
|
||||
assert "region" not in location
|
||||
|
||||
def test_only_pass_findings(self):
|
||||
findings = [
|
||||
generate_finding_output(status="PASS"),
|
||||
|
||||
Reference in New Issue
Block a user