codeanalyzer-python 0.1.1__py3-none-any.whl → 0.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- codeanalyzer/__init__.py +0 -0
- codeanalyzer/__main__.py +84 -0
- codeanalyzer/core.py +321 -0
- codeanalyzer/jedi/__init__.py +0 -0
- codeanalyzer/jedi/jedi.py +0 -0
- codeanalyzer/py.typed +0 -0
- codeanalyzer/schema/__init__.py +23 -0
- codeanalyzer/schema/py_schema.py +360 -0
- codeanalyzer/semantic_analysis/__init__.py +0 -0
- codeanalyzer/semantic_analysis/codeql/__init__.py +26 -0
- codeanalyzer/semantic_analysis/codeql/codeql_analysis.py +133 -0
- codeanalyzer/semantic_analysis/codeql/codeql_exceptions.py +12 -0
- codeanalyzer/semantic_analysis/codeql/codeql_loader.py +74 -0
- codeanalyzer/semantic_analysis/codeql/codeql_query_runner.py +164 -0
- codeanalyzer/semantic_analysis/wala/__init__.py +15 -0
- codeanalyzer/syntactic_analysis/__init__.py +0 -0
- codeanalyzer/syntactic_analysis/symbol_table_builder.py +903 -0
- codeanalyzer/utils/__init__.py +5 -0
- codeanalyzer/utils/logging.py +18 -0
- codeanalyzer/utils/progress_bar.py +69 -0
- {codeanalyzer_python-0.1.1.dist-info → codeanalyzer_python-0.1.3.dist-info}/METADATA +3 -3
- codeanalyzer_python-0.1.3.dist-info/RECORD +26 -0
- codeanalyzer_python-0.1.1.dist-info/RECORD +0 -6
- {codeanalyzer_python-0.1.1.dist-info → codeanalyzer_python-0.1.3.dist-info}/WHEEL +0 -0
- {codeanalyzer_python-0.1.1.dist-info → codeanalyzer_python-0.1.3.dist-info}/entry_points.txt +0 -0
- {codeanalyzer_python-0.1.1.dist-info → codeanalyzer_python-0.1.3.dist-info}/licenses/LICENSE +0 -0
- {codeanalyzer_python-0.1.1.dist-info → codeanalyzer_python-0.1.3.dist-info}/licenses/NOTICE +0 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
################################################################################
|
|
2
|
+
# Copyright IBM Corporation 2025
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
################################################################################
|
|
16
|
+
|
|
17
|
+
"""Backend module for CodeQL query execution.
|
|
18
|
+
|
|
19
|
+
This module provides functionality to run CodeQL queries against CodeQL databases
|
|
20
|
+
and process the results.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
import subprocess
|
|
24
|
+
import tempfile
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
import shlex
|
|
27
|
+
from typing import List
|
|
28
|
+
import pandas as pd
|
|
29
|
+
from pandas import DataFrame
|
|
30
|
+
|
|
31
|
+
from codeanalyzer.semantic_analysis.codeql.codeql_exceptions import CodeQLExceptions
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class CodeQLQueryRunner:
|
|
35
|
+
"""A class for executing CodeQL queries against a CodeQL database.
|
|
36
|
+
|
|
37
|
+
This class provides a context manager interface for executing CodeQL queries
|
|
38
|
+
and handling temporary resources needed during query execution.
|
|
39
|
+
|
|
40
|
+
Args:
|
|
41
|
+
database_path (str): The path to the CodeQL database.
|
|
42
|
+
|
|
43
|
+
Attributes:
|
|
44
|
+
database_path (Path): The path to the CodeQL database.
|
|
45
|
+
temp_file_path (Path): The path to the temporary query file.
|
|
46
|
+
csv_output_file (Path): The path to the CSV output file.
|
|
47
|
+
temp_bqrs_file_path (Path): The path to the temporary bqrs file.
|
|
48
|
+
temp_qlpack_file (Path): The path to the temporary qlpack file.
|
|
49
|
+
|
|
50
|
+
Raises:
|
|
51
|
+
CodeQLQueryExecutionException: If there is an error executing the query.
|
|
52
|
+
"""
|
|
53
|
+
|
|
54
|
+
def __init__(self, database_path: str):
|
|
55
|
+
self.database_path: Path = Path(database_path)
|
|
56
|
+
self.temp_file_path: Path = None
|
|
57
|
+
|
|
58
|
+
def __enter__(self):
|
|
59
|
+
"""Context entry that creates temporary files to execute a CodeQL query.
|
|
60
|
+
|
|
61
|
+
Returns:
|
|
62
|
+
CodeQLQueryRunner: The instance of the class.
|
|
63
|
+
|
|
64
|
+
Note:
|
|
65
|
+
This method creates temporary files to hold the query and store their paths.
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
# Create a temporary file to hold the query and store its path
|
|
69
|
+
temp_file = tempfile.NamedTemporaryFile("w", delete=False, suffix=".ql")
|
|
70
|
+
csv_file = tempfile.NamedTemporaryFile("w", delete=False, suffix=".csv")
|
|
71
|
+
bqrs_file = tempfile.NamedTemporaryFile("w", delete=False, suffix=".bqrs")
|
|
72
|
+
self.temp_file_path = Path(temp_file.name)
|
|
73
|
+
self.csv_output_file = Path(csv_file.name)
|
|
74
|
+
self.temp_bqrs_file_path = Path(bqrs_file.name)
|
|
75
|
+
|
|
76
|
+
# Let's close the files, we'll reopen them by path when needed.
|
|
77
|
+
temp_file.close()
|
|
78
|
+
bqrs_file.close()
|
|
79
|
+
csv_file.close()
|
|
80
|
+
|
|
81
|
+
# Create a temporary qlpack.yml file
|
|
82
|
+
self.temp_qlpack_file = self.temp_file_path.parent / "qlpack.yml"
|
|
83
|
+
with self.temp_qlpack_file.open("w") as f:
|
|
84
|
+
f.write("name: temp\n")
|
|
85
|
+
f.write("version: 1.0.0\n")
|
|
86
|
+
f.write("libraryPathDependencies: codeql/java-all\n")
|
|
87
|
+
|
|
88
|
+
return self
|
|
89
|
+
|
|
90
|
+
def execute(self, query_string: str, column_names: List[str]) -> DataFrame:
|
|
91
|
+
"""Writes the query to the temporary file and executes it against the specified CodeQL database.
|
|
92
|
+
|
|
93
|
+
Args:
|
|
94
|
+
query_string (str): The CodeQL query string to be executed.
|
|
95
|
+
column_names (List[str]): The list of column names for the CSV the CodeQL produces when we execute the query.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
dict: A dictionary containing the resulting DataFrame.
|
|
99
|
+
|
|
100
|
+
Raises:
|
|
101
|
+
RuntimeError: If the context manager is not entered using the 'with' statement.
|
|
102
|
+
CodeQLQueryExecutionException: If there is an error executing the query.
|
|
103
|
+
"""
|
|
104
|
+
if not self.temp_file_path:
|
|
105
|
+
raise RuntimeError("CodeQLQueryRunner not entered using 'with' statement.")
|
|
106
|
+
|
|
107
|
+
# Write the query to the temp file so we can execute it.
|
|
108
|
+
self.temp_file_path.write_text(query_string)
|
|
109
|
+
|
|
110
|
+
# Construct and execute the CodeQL CLI command asking for a JSON output.
|
|
111
|
+
codeql_query_cmd = shlex.split(
|
|
112
|
+
f"codeql query run {self.temp_file_path} --database={self.database_path} --output={self.temp_bqrs_file_path}",
|
|
113
|
+
posix=False,
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
call = subprocess.Popen(codeql_query_cmd, stdout=None, stderr=None)
|
|
117
|
+
_, err = call.communicate()
|
|
118
|
+
if call.returncode != 0:
|
|
119
|
+
raise CodeQLExceptions.CodeQLQueryExecutionException(
|
|
120
|
+
f"Error executing query: {err.stderr}"
|
|
121
|
+
)
|
|
122
|
+
|
|
123
|
+
# Convert the bqrs file to a CSV file
|
|
124
|
+
bqrs2csv_command = shlex.split(
|
|
125
|
+
f"codeql bqrs decode --format=csv --output={self.csv_output_file} {self.temp_bqrs_file_path}",
|
|
126
|
+
posix=False,
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# Read the CSV file content and cast it to a DataFrame
|
|
130
|
+
|
|
131
|
+
call = subprocess.Popen(bqrs2csv_command, stdout=None, stderr=None)
|
|
132
|
+
_, err = call.communicate()
|
|
133
|
+
if call.returncode != 0:
|
|
134
|
+
raise CodeQLExceptions.CodeQLQueryExecutionException(
|
|
135
|
+
f"Error executing query: {err.stderr}"
|
|
136
|
+
)
|
|
137
|
+
else:
|
|
138
|
+
return pd.read_csv(
|
|
139
|
+
self.csv_output_file,
|
|
140
|
+
header=None,
|
|
141
|
+
names=column_names,
|
|
142
|
+
skiprows=[0],
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
146
|
+
"""Clean up resources used by the CodeQL analysis.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
exc_type: The exception type if an exception was raised in the context, otherwise None.
|
|
150
|
+
exc_val: The exception instance if an exception was raised in the context, otherwise None.
|
|
151
|
+
exc_tb: The traceback if an exception was raised in the context, otherwise None.
|
|
152
|
+
|
|
153
|
+
Note:
|
|
154
|
+
Deletes the temporary files created during the analysis, including the temporary file path,
|
|
155
|
+
the CSV output file, and the temporary QL pack file.
|
|
156
|
+
"""
|
|
157
|
+
if self.temp_file_path and self.temp_file_path.exists():
|
|
158
|
+
self.temp_file_path.unlink()
|
|
159
|
+
|
|
160
|
+
if self.csv_output_file and self.csv_output_file.exists():
|
|
161
|
+
self.csv_output_file.unlink()
|
|
162
|
+
|
|
163
|
+
if self.temp_qlpack_file and self.temp_qlpack_file.exists():
|
|
164
|
+
self.temp_qlpack_file.unlink()
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
################################################################################
|
|
2
|
+
# Copyright IBM Corporation 2025
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
################################################################################
|
|
File without changes
|