forked from pixee/codemodder-python
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcodeql.py
More file actions
73 lines (59 loc) · 2.59 KB
/
codeql.py
File metadata and controls
73 lines (59 loc) · 2.59 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
69
70
71
72
73
import json
from pathlib import Path
from typing_extensions import Self
from codemodder.result import LineInfo, Location, Result, ResultSet
from codemodder.sarifs import AbstractSarifToolDetector
class CodeQLSarifToolDetector(AbstractSarifToolDetector):
@classmethod
def detect(cls, run_data: dict) -> bool:
return "tool" in run_data and "CodeQL" in run_data["tool"]["driver"]["name"]
class CodeQLLocation(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"].get("startColumn"),
)
end = LineInfo(
line=sarif_location["physicalLocation"]["region"].get(
"endLine", start.line
),
column=sarif_location["physicalLocation"]["region"].get(
"endColumn", start.column
),
)
return cls(file=file, start=start, end=end)
class CodeQLResult(Result):
@classmethod
def from_sarif(
cls, sarif_result, sarif_run, rule_extensions, truncate_rule_id: bool = False
) -> Self:
extension_index = sarif_result["rule"]["toolComponent"]["index"]
tool_index = sarif_result["rule"]["index"]
rule_data = rule_extensions[extension_index]["rules"][tool_index]
locations: list[Location] = []
for location in sarif_result["locations"]:
try:
codeql_location = CodeQLLocation.from_sarif(location)
except KeyError:
# TODO: handle this case more gracefully
continue
locations.append(codeql_location)
return cls(rule_id=rule_data["id"], locations=locations)
class CodeQLResultSet(ResultSet):
@classmethod
def from_sarif(cls, sarif_file: str | Path, truncate_rule_id: bool = False) -> Self:
with open(sarif_file, "r", encoding="utf-8") as f:
data = json.load(f)
result_set = cls()
for sarif_run in data["runs"]:
rule_extensions = sarif_run["tool"]["extensions"]
if CodeQLSarifToolDetector.detect(sarif_run):
for sarif_result in sarif_run["results"]:
codeql_result = CodeQLResult.from_sarif(
sarif_result, sarif_run, rule_extensions, truncate_rule_id
)
result_set.add_result(codeql_result)
return result_set