-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathsarifs.py
More file actions
68 lines (53 loc) · 2.47 KB
/
sarifs.py
File metadata and controls
68 lines (53 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import json
from pathlib import Path
from typing import Optional
from typing_extensions import Self
from .result import ResultSet, Result, Location, LineInfo
def extract_rule_id(result, sarif_run) -> Optional[str]:
if "ruleId" in result:
# semgrep preprends the folders into the rule-id, we want the base name only
return result["ruleId"].rsplit(".")[-1]
# it may be contained in the 'rule' field through the tool component in the sarif file
if "rule" in result:
tool_index = result["rule"]["toolComponent"]["index"]
rule_index = result["rule"]["index"]
return sarif_run["tool"]["extensions"][tool_index]["rules"][rule_index]["id"]
return None
class SarifLocation(Location):
@classmethod
def from_sarif(cls, sarif_location) -> Self:
artifact_location = sarif_location["physicalLocation"]["artifactLocation"]
file = Path(artifact_location["uri"])
start = LineInfo(
line=sarif_location["physicalLocation"]["region"]["startLine"],
column=sarif_location["physicalLocation"]["region"]["startColumn"],
snippet=sarif_location["physicalLocation"]["region"]["snippet"]["text"],
)
end = LineInfo(
line=sarif_location["physicalLocation"]["region"]["endLine"],
column=sarif_location["physicalLocation"]["region"]["endColumn"],
snippet=sarif_location["physicalLocation"]["region"]["snippet"]["text"],
)
return cls(file=file, start=start, end=end)
class SarifResult(Result):
@classmethod
def from_sarif(cls, sarif_result, sarif_run) -> Self:
rule_id = extract_rule_id(sarif_result, sarif_run)
if not rule_id:
raise ValueError("Could not extract rule id from sarif result.")
locations: list[Location] = []
for location in sarif_result["locations"]:
artifact_location = SarifLocation.from_sarif(location)
locations.append(artifact_location)
return cls(rule_id=rule_id, locations=locations)
class SarifResultSet(ResultSet):
@classmethod
def from_sarif(cls, sarif_file: str | Path) -> Self:
with open(sarif_file, "r", encoding="utf-8") as f:
data = json.load(f)
result_set = cls()
for sarif_run in data["runs"]:
for result in sarif_run["results"]:
sarif_result = SarifResult.from_sarif(result, sarif_run)
result_set.add_result(sarif_result)
return result_set