Skip to content

Commit ae6c5af

Browse files
committed
check, fix, and format code with new ruff version
1 parent bc494a7 commit ae6c5af

File tree

27 files changed

+100
-55
lines changed

27 files changed

+100
-55
lines changed

src/analysis/YaraPluginBase.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,12 @@ def _append_match_to_result(match, resulting_matches: dict[str, dict], rule):
105105

106106

107107
def _parse_meta_data(meta_data_string: str) -> dict[str, str | bool | int]:
108-
'''
108+
"""
109109
Will be of form 'item0=lowercaseboolean0,item1="str1",item2=int2,...'
110-
'''
110+
"""
111111
try:
112112
# YARA insert backslashes before single quotes in the meta output and the YAML parser doesn't like that
113-
meta_data_string = meta_data_string.replace(r"\'", "'")
113+
meta_data_string = meta_data_string.replace(r'\'', "'")
114114
meta_data = yaml.safe_load(f'{{{meta_data_string.replace("=", ": ")}}}')
115115
assert isinstance(meta_data, dict)
116116
return meta_data

src/helperFunctions/install.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def remove_folder(folder_name: str):
5353
shutil.rmtree(folder_name)
5454
except PermissionError:
5555
logging.debug(f'Falling back on root permission for deleting {folder_name}')
56-
subprocess.run(f'sudo rm -rf {folder_name}', shell=True)
56+
subprocess.run(f'sudo rm -rf {folder_name}', shell=True, check=False)
5757
except Exception as exception:
5858
raise InstallationError(exception) from None
5959

@@ -70,7 +70,7 @@ def log_current_packages(packages: tuple[str], install: bool = True):
7070

7171

7272
def _run_shell_command_raise_on_return_code(command: str, error: str, add_output_on_error=False) -> str:
73-
cmd_process = subprocess.run(command, shell=True, stdout=PIPE, stderr=STDOUT, text=True)
73+
cmd_process = subprocess.run(command, shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False)
7474
if cmd_process.returncode != 0:
7575
if add_output_on_error:
7676
error = f'{error}\n{cmd_process.stdout}'
@@ -151,7 +151,9 @@ def check_if_command_in_path(command: str) -> bool:
151151
152152
:param command: Command to check.
153153
"""
154-
command_process = subprocess.run(f'command -v {command}', shell=True, stdout=DEVNULL, stderr=DEVNULL, text=True)
154+
command_process = subprocess.run(
155+
f'command -v {command}', shell=True, stdout=DEVNULL, stderr=DEVNULL, text=True, check=False
156+
)
155157
return command_process.returncode == 0
156158

157159

@@ -178,7 +180,7 @@ def install_github_project(project_path: str, commands: list[str]):
178180
with OperateInDirectory(folder_name, remove=True):
179181
error = None
180182
for command in commands:
181-
cmd_process = subprocess.run(command, shell=True, stdout=PIPE, stderr=STDOUT, text=True)
183+
cmd_process = subprocess.run(command, shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False)
182184
if cmd_process.returncode != 0:
183185
error = f'Error while processing github project {project_path}!\n{cmd_process.stdout}'
184186
break
@@ -189,7 +191,9 @@ def install_github_project(project_path: str, commands: list[str]):
189191

190192
def _checkout_github_project(github_path: str, folder_name: str):
191193
clone_url = f'https://www.github.com/{github_path}'
192-
git_process = subprocess.run(f'git clone {clone_url}', shell=True, stdout=DEVNULL, stderr=DEVNULL, text=True)
194+
git_process = subprocess.run(
195+
f'git clone {clone_url}', shell=True, stdout=DEVNULL, stderr=DEVNULL, text=True, check=False
196+
)
193197
if git_process.returncode != 0:
194198
raise InstallationError(f'Cloning from github failed for project {github_path}\n {clone_url}')
195199
if not Path('.', folder_name).exists():

src/helperFunctions/yara_binary_search.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ def _execute_yara_search(self, rule_file_path: str, target_path: str | None = No
3838
"""
3939
compiled_flag = '-C' if Path(rule_file_path).read_bytes().startswith(b'YARA') else ''
4040
command = f'yara -r {compiled_flag} {rule_file_path} {target_path or self.db_path}'
41-
yara_process = subprocess.run(command, shell=True, stdout=PIPE, stderr=STDOUT, text=True)
41+
yara_process = subprocess.run(command, shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False)
4242
return yara_process.stdout
4343

4444
def _execute_yara_search_for_single_firmware(self, rule_file_path: str, firmware_uid: str) -> str:

src/install.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,9 @@ def install_statistic_cronjob():
149149
crontab_file_path = current_dir.parent / 'update_statistic.cron'
150150
cron_content = f'0 * * * * {statistic_update_script_path} > /dev/null 2>&1\n'
151151
crontab_file_path.write_text(cron_content)
152-
crontab_process = subprocess.run(f'crontab {crontab_file_path}', shell=True, stdout=PIPE, stderr=STDOUT, text=True)
152+
crontab_process = subprocess.run(
153+
f'crontab {crontab_file_path}', shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False
154+
)
153155
if crontab_process.returncode != 0:
154156
logging.error(crontab_process.stdout)
155157
else:

src/install/backend.py

+17-9
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def main(skip_docker, distribution):
5555
shell=True,
5656
capture_output=True,
5757
text=True,
58+
check=False,
5859
)
5960
if yarac_process.returncode != 0:
6061
raise InstallationError('Failed to compile yara test signatures')
@@ -72,7 +73,7 @@ def _install_docker_images():
7273
logging.info('Pulling fact extraction container')
7374

7475
docker_process = subprocess.run(
75-
'docker pull fkiecad/fact_extractor', shell=True, stdout=PIPE, stderr=STDOUT, text=True
76+
'docker pull fkiecad/fact_extractor', shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False
7677
)
7778
if docker_process.returncode != 0:
7879
raise InstallationError(f'Failed to pull extraction container:\n{docker_process.stdout}')
@@ -89,10 +90,15 @@ def _create_firmware_directory():
8990

9091
data_dir_name = config.backend.firmware_file_storage_directory
9192
mkdir_process = subprocess.run(
92-
f'sudo mkdir -p --mode=0744 {data_dir_name}', shell=True, stdout=PIPE, stderr=STDOUT, text=True
93+
f'sudo mkdir -p --mode=0744 {data_dir_name}', shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False
9394
)
9495
chown_process = subprocess.run(
95-
f'sudo chown {os.getuid()}:{os.getgid()} {data_dir_name}', shell=True, stdout=PIPE, stderr=STDOUT, text=True
96+
f'sudo chown {os.getuid()}:{os.getgid()} {data_dir_name}',
97+
shell=True,
98+
stdout=PIPE,
99+
stderr=STDOUT,
100+
text=True,
101+
check=False,
96102
)
97103
if not all(code == 0 for code in (mkdir_process.returncode, chown_process.returncode)):
98104
raise InstallationError(
@@ -122,26 +128,28 @@ def _install_plugins(distribution, skip_docker, only_docker=False):
122128
def _install_yara():
123129
yara_version = 'v4.2.3' # must be the same version as `yara-python` in `install/requirements_common.txt`
124130

125-
yara_process = subprocess.run('yara --version', shell=True, stdout=PIPE, stderr=STDOUT, text=True)
131+
yara_process = subprocess.run('yara --version', shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False)
126132
if yara_process.returncode == 0 and yara_process.stdout.strip() == yara_version.strip('v'):
127133
logging.info('Skipping yara installation: Already installed and up to date')
128134
return
129135

130136
logging.info(f'Installing yara {yara_version}')
131137
archive = f'{yara_version}.zip'
132138
download_url = f'https://github.com/VirusTotal/yara/archive/refs/tags/{archive}'
133-
wget_process = subprocess.run(f'wget {download_url}', shell=True, stdout=PIPE, stderr=STDOUT, text=True)
139+
wget_process = subprocess.run(
140+
f'wget {download_url}', shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False
141+
)
134142
if wget_process.returncode != 0:
135143
raise InstallationError(f'Error on yara download.\n{wget_process.stdout}')
136-
unzip_process = subprocess.run(f'unzip {archive}', shell=True, stdout=PIPE, stderr=STDOUT, text=True)
144+
unzip_process = subprocess.run(f'unzip {archive}', shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False)
137145
Path(archive).unlink()
138146
if unzip_process.returncode != 0:
139147
raise InstallationError(f'Error on yara extraction.\n{unzip_process.stdout}')
140-
yara_folder = [p for p in Path('.').iterdir() if p.name.startswith('yara-')][0]
148+
yara_folder = [p for p in Path().iterdir() if p.name.startswith('yara-')][0]
141149
with OperateInDirectory(yara_folder.name, remove=True):
142150
os.chmod('bootstrap.sh', 0o775) # noqa: PTH101
143151
for command in ['./bootstrap.sh', './configure --enable-magic', 'make -j$(nproc)', 'sudo make install']:
144-
cmd_process = subprocess.run(command, shell=True, stdout=PIPE, stderr=STDOUT, text=True)
152+
cmd_process = subprocess.run(command, shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False)
145153
if cmd_process.returncode != 0:
146154
raise InstallationError(f'Error in yara installation.\n{cmd_process.stdout}')
147155

@@ -152,7 +160,7 @@ def _install_checksec():
152160
logging.info('Installing checksec.sh')
153161
checksec_url = 'https://raw.githubusercontent.com/slimm609/checksec.sh/2.5.0/checksec'
154162
wget_process = subprocess.run(
155-
f'wget -P {BIN_DIR} {checksec_url}', shell=True, stdout=PIPE, stderr=STDOUT, text=True
163+
f'wget -P {BIN_DIR} {checksec_url}', shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False
156164
)
157165
if wget_process.returncode != 0:
158166
raise InstallationError(f'Error during installation of checksec.sh\n{wget_process.stdout}')

src/install/frontend.py

+11-6
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
def execute_commands_and_raise_on_return_code(commands, error=None):
2828
for command in commands:
2929
bad_return = error if error else f'execute {command}'
30-
cmd_process = subprocess.run(command, shell=True, stdout=PIPE, stderr=STDOUT, text=True)
30+
cmd_process = subprocess.run(command, shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False)
3131
if cmd_process.returncode != 0:
3232
raise InstallationError(f'Failed to {bad_return}\n{cmd_process.stdout}')
3333

@@ -40,10 +40,15 @@ def _create_directory_for_authentication():
4040
factauthdir = '/'.join(dburi.split('/')[:-1])[10:] # FIXME this should be beautified with pathlib
4141

4242
mkdir_process = subprocess.run(
43-
f'sudo mkdir -p --mode=0744 {factauthdir}', shell=True, stdout=PIPE, stderr=STDOUT, text=True
43+
f'sudo mkdir -p --mode=0744 {factauthdir}', shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False
4444
)
4545
chown_process = subprocess.run(
46-
f'sudo chown {os.getuid()}:{os.getgid()} {factauthdir}', shell=True, stdout=PIPE, stderr=STDOUT, text=True
46+
f'sudo chown {os.getuid()}:{os.getgid()} {factauthdir}',
47+
shell=True,
48+
stdout=PIPE,
49+
stderr=STDOUT,
50+
text=True,
51+
check=False,
4752
)
4853

4954
if not all(return_code == 0 for return_code in [mkdir_process.returncode, chown_process.returncode]):
@@ -70,7 +75,7 @@ def _install_nginx(distribution):
7075
],
7176
error='restore selinux context',
7277
)
73-
nginx_process = subprocess.run('sudo nginx -s reload', shell=True, capture_output=True, text=True)
78+
nginx_process = subprocess.run('sudo nginx -s reload', shell=True, capture_output=True, text=True, check=False)
7479
if nginx_process.returncode != 0:
7580
raise InstallationError(f'Failed to start nginx\n{nginx_process.stderr}')
7681

@@ -109,15 +114,15 @@ def _install_docker_images(radare):
109114

110115
with OperateInDirectory('radare'):
111116
docker_compose_process = subprocess.run(
112-
'docker compose build', shell=True, stdout=PIPE, stderr=STDOUT, text=True
117+
'docker compose build', shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False
113118
)
114119
if docker_compose_process.returncode != 0:
115120
raise InstallationError(f'Failed to initialize radare container:\n{docker_compose_process.stdout}')
116121

117122
# pull pdf report container
118123
logging.info('Pulling pdf report container')
119124
docker_process = subprocess.run(
120-
'docker pull fkiecad/fact_pdf_report', shell=True, stdout=PIPE, stderr=STDOUT, text=True
125+
'docker pull fkiecad/fact_pdf_report', shell=True, stdout=PIPE, stderr=STDOUT, text=True, check=False
121126
)
122127
if docker_process.returncode != 0:
123128
raise InstallationError(f'Failed to pull pdf report container:\n{docker_process.stdout}')

src/plugins/analysis/architecture_detection/internal/dt.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ def _get_compatible_entry(dts: str) -> str | None:
5858
break
5959

6060
cpu = cpus[cpu_name]
61-
if 'compatible' not in cpu.keys():
61+
if 'compatible' not in cpu:
6262
continue
6363

6464
compatible = cpu['compatible']

src/plugins/analysis/binwalk/code/binwalk.py

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ def process_object(self, file_object):
2929
stdout=PIPE,
3030
stderr=STDOUT,
3131
text=True,
32+
check=False,
3233
)
3334
signature_analysis_result = cmd_process.stdout
3435
try:

src/plugins/analysis/checksec/code/checksec.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,12 @@ def process_object(self, file_object):
3939

4040
def execute_checksec_script(file_path):
4141
checksec_process = subprocess.run(
42-
f'{SHELL_SCRIPT} --file={file_path} --format=json --extended', shell=True, stdout=PIPE, stderr=STDOUT, text=True
42+
f'{SHELL_SCRIPT} --file={file_path} --format=json --extended',
43+
shell=True,
44+
stdout=PIPE,
45+
stderr=STDOUT,
46+
text=True,
47+
check=False,
4348
)
4449
if checksec_process.returncode != 0:
4550
raise ValueError(f'Checksec script exited with non-zero return code {checksec_process.returncode}')

src/plugins/analysis/cve_lookup/code/cve_lookup.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def process_object(self, file_object: FileObject) -> FileObject:
4141
cves = {'cve_results': {}}
4242
connection = DbConnection(f'sqlite:///{DB_PATH}')
4343
lookup = Lookup(file_object, connection)
44-
for _key, value in file_object.processed_analysis['software_components']['result'].items():
44+
for value in file_object.processed_analysis['software_components']['result'].values():
4545
product = value['meta']['software_name']
4646
version = value['meta']['version'][0]
4747
if product and version:

src/plugins/analysis/device_tree/internal/device_tree_utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ def header_has_illegal_values(header: DeviceTreeHeader, max_size: int) -> bool:
8080

8181

8282
def convert_device_tree_to_str(file_path: str | Path) -> str | None:
83-
process = run(f'dtc -I dtb -O dts {file_path}', shell=True, capture_output=True)
83+
process = run(f'dtc -I dtb -O dts {file_path}', shell=True, capture_output=True, check=False)
8484
if process.returncode != 0:
8585
logging.warning(
8686
f'The Device Tree Compiler exited with non-zero return code {process.returncode}: {process.stderr}'

src/plugins/analysis/file_type/code/file_type.py

+7-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
1+
from __future__ import annotations
2+
3+
import typing
4+
15
from fact_helper_file import get_file_type_from_path
26
import pydantic
37
from pydantic import Field
48

59
from analysis.plugin import AnalysisPluginV0
610
from analysis.plugin.compat import AnalysisBasePluginAdapterMixin
711

8-
import io
912
from typing import List
1013

14+
if typing.TYPE_CHECKING:
15+
import io
16+
1117

1218
class AnalysisPlugin(AnalysisPluginV0, AnalysisBasePluginAdapterMixin):
1319
class Schema(pydantic.BaseModel):

src/plugins/analysis/kernel_config/internal/checksec_check_kernel.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def check_kernel_config(kernel_config: str) -> dict:
4747
fp.write(kernel_config.encode())
4848
fp.seek(0)
4949
command = f'{CHECKSEC_PATH} --kernel={fp.name} --output=json'
50-
checksec_process = subprocess.run(command, shell=True, stdout=PIPE, stderr=DEVNULL, text=True)
50+
checksec_process = subprocess.run(command, shell=True, stdout=PIPE, stderr=DEVNULL, text=True, check=False)
5151
result = json.loads(checksec_process.stdout)
5252
whitelist_configs(result)
5353
return result

src/plugins/analysis/kernel_config/internal/kernel_config_hardening_check.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ def _get_kernel_hardening_data(kernel_config: str) -> list[list[str]]:
137137
stdout=PIPE,
138138
stderr=STDOUT,
139139
text=True,
140+
check=False,
140141
)
141142
return json.loads(kconfig_process.stdout)
142143
except (JSONDecodeError, KeyError):
@@ -155,11 +156,11 @@ def _add_protection_info(hardening_result: list[list[str]]) -> list[HardeningChe
155156

156157

157158
def _detach_actual_value_from_result(single_result: list[str]) -> str:
158-
'''
159+
"""
159160
the result may contain the actual value after a colon
160161
e.g. 'FAIL: not found' or 'FAIL: "y"'
161162
removes actual value and returns it (or empty string if missing)
162-
'''
163+
"""
163164
split_result = single_result[4].split(': ')
164165
single_result[4] = split_result[0]
165166
return ': '.join(split_result[1:]).replace('"', '')

src/plugins/analysis/kernel_config/test/test_kernel_config.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import glob
21
from pathlib import Path
32
from subprocess import CompletedProcess
43

@@ -81,7 +80,7 @@ def test_extract_ko_success(self, analysis_plugin):
8180
assert analysis_plugin.probably_kernel_config(result)
8281

8382
def test_process_objects_kernel_image(self, analysis_plugin):
84-
for valid_image in glob.glob(str(TEST_DATA_DIR / 'synthetic/*.image')):
83+
for valid_image in (TEST_DATA_DIR / 'synthetic').glob('*.image'):
8584
test_file = FileObject(file_path=str(valid_image))
8685
test_file.processed_analysis['file_type'] = {'result': {'mime': 'application/octet-stream'}}
8786
test_file.processed_analysis['software_components'] = {'summary': ['Linux Kernel']}
@@ -91,7 +90,7 @@ def test_process_objects_kernel_image(self, analysis_plugin):
9190
assert test_file.processed_analysis[analysis_plugin.NAME]['is_kernel_config']
9291
assert len(test_file.processed_analysis[analysis_plugin.NAME]['kernel_config']) > 0
9392

94-
for bad_image in glob.glob(str(TEST_DATA_DIR / 'random_invalid/*.image')):
93+
for bad_image in (TEST_DATA_DIR / 'random_invalid').glob('*.image'):
9594
test_file = FileObject(file_path=str(bad_image))
9695
test_file.processed_analysis['file_type'] = {'result': {'mime': 'application/octet-stream'}}
9796
test_file.processed_analysis['software_components'] = {'summary': ['Linux Kernel']}
@@ -149,7 +148,7 @@ def test_try_extract_fail():
149148

150149

151150
def test_try_extract_random_fail():
152-
for fp in glob.glob(str(TEST_DATA_DIR / 'random_invalid/*.image')):
151+
for fp in (TEST_DATA_DIR / 'random_invalid').glob('*.image'):
153152
test_file = FileObject(file_path=fp)
154153
test_file.processed_analysis['file_type'] = {'result': {'mime': 'application/octet-stream'}}
155154
test_file.processed_analysis['software_components'] = {'summary': ['Linux Kernel']}

src/plugins/analysis/known_vulnerabilities/internal/rulebook.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ def __init__(self, rule, description, reliability, score, link, short_name): #
3232

3333
def _make_type_assertions(self, link, rule):
3434
for type_assertion, error_message in [
35-
(int(self.reliability) in range(0, 101), 'reliability must be between 0 and 100'),
35+
(int(self.reliability) in range(101), 'reliability must be between 0 and 100'),
3636
(self.score in ['low', 'medium', 'high'], 'score has to be one of low, medium or high'),
3737
(isinstance(self.description, str), 'description must be a string'),
3838
(

src/scheduler/analysis/plugin.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from __future__ import annotations
2+
13
import ctypes
24
import io
35
import logging
@@ -14,11 +16,13 @@
1416
from pydantic import BaseModel, ConfigDict
1517

1618
import config
17-
from analysis.plugin import AnalysisPluginV0
18-
from objects.file import FileObject
1919
from statistic.analysis_stats import ANALYSIS_STATS_LIMIT
2020
from storage.fsorganizer import FSOrganizer
2121

22+
if typing.TYPE_CHECKING:
23+
from analysis.plugin import AnalysisPluginV0
24+
from objects.file import FileObject
25+
2226

2327
class PluginRunner:
2428
class Config(BaseModel):

src/scheduler/analysis/scheduler.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -610,7 +610,7 @@ def check_exceptions(self) -> bool:
610610
611611
:return: Boolean value stating if any attached process ran into an exception
612612
"""
613-
for _, plugin in self.analysis_plugins.items():
613+
for plugin in self.analysis_plugins.values():
614614
if isinstance(plugin, AnalysisPluginV0):
615615
continue
616616
if plugin.check_exceptions():

src/start_fact_frontend.py

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
along with this program. If not, see <http://www.gnu.org/licenses/>.
1818
"""
1919

20+
from __future__ import annotations
21+
2022
import logging
2123
import pickle
2224
import signal

0 commit comments

Comments
 (0)