From 9a3507422cccd1435297784398914a44bc174004 Mon Sep 17 00:00:00 2001 From: JeffreyChen Date: Sat, 25 Apr 2026 16:09:11 +0800 Subject: [PATCH 1/2] fix: clear remaining Codacy findings - Validate package names against a strict module-identifier regex before find_spec/import_module so user-controlled inputs cannot reach dynamic import (Semgrep non-literal-import). - Use Sphinx project_copyright instead of redefining the copyright builtin in docs/source/conf.py (Pylint W0622). - Drop unused imports flagged by Prospector pyflakes in test_executor, test_get_dir_file_list, and test_json_file. --- docs/source/conf.py | 2 +- .../utils/package_manager/package_manager_class.py | 13 ++++++++++++- test/unit_test/test_executor.py | 3 --- test/unit_test/test_get_dir_file_list.py | 1 - test/unit_test/test_json_file.py | 3 --- 5 files changed, 13 insertions(+), 9 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 487ce71..d3cd1c8 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -16,7 +16,7 @@ # -- Project information ----------------------------------------------------- project = "MailThunder" -copyright = "2020 ~ Now, JE-Chen" +project_copyright = "2020 ~ Now, JE-Chen" author = "JE-Chen" # -- General configuration --------------------------------------------------- diff --git a/je_mail_thunder/utils/package_manager/package_manager_class.py b/je_mail_thunder/utils/package_manager/package_manager_class.py index 078c2bd..6a68814 100644 --- a/je_mail_thunder/utils/package_manager/package_manager_class.py +++ b/je_mail_thunder/utils/package_manager/package_manager_class.py @@ -1,9 +1,16 @@ +import re from importlib import import_module from importlib.util import find_spec from inspect import getmembers, isfunction, isbuiltin, isclass from je_mail_thunder.utils.logging.loggin_instance import mail_thunder_logger +_MODULE_NAME_PATTERN = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$") + + +def _is_safe_module_name(package: str) -> bool: + return isinstance(package, str) and bool(_MODULE_NAME_PATTERN.fullmatch(package)) + class PackageManager: @@ -17,9 +24,13 @@ def check_package(self, package: str): :param package: package to check exists or not :return: package if find else None """ + if not _is_safe_module_name(package): + mail_thunder_logger.error( + f"check_package: rejected non-conforming module name: {package!r}") + return None if self.installed_package_dict.get(package, None) is None: found_spec = find_spec(package) - if found_spec is not None: + if found_spec is not None and _is_safe_module_name(found_spec.name): try: installed_package = import_module(found_spec.name) self.installed_package_dict.update( diff --git a/test/unit_test/test_executor.py b/test/unit_test/test_executor.py index e50d530..2680a4c 100644 --- a/test/unit_test/test_executor.py +++ b/test/unit_test/test_executor.py @@ -1,6 +1,3 @@ -import os -import types - import pytest from je_mail_thunder.utils.exception.exceptions import AddCommandException, ExecuteActionException diff --git a/test/unit_test/test_get_dir_file_list.py b/test/unit_test/test_get_dir_file_list.py index 1fd1305..4fbc906 100644 --- a/test/unit_test/test_get_dir_file_list.py +++ b/test/unit_test/test_get_dir_file_list.py @@ -1,5 +1,4 @@ import os -import shutil import tempfile from je_mail_thunder.utils.file_process.get_dir_file_list import get_dir_files_as_list diff --git a/test/unit_test/test_json_file.py b/test/unit_test/test_json_file.py index d920b8b..76d06b1 100644 --- a/test/unit_test/test_json_file.py +++ b/test/unit_test/test_json_file.py @@ -1,9 +1,6 @@ import json import os -import pytest - -from je_mail_thunder.utils.exception.exceptions import JsonActionException from je_mail_thunder.utils.json.json_file import read_action_json, write_action_json TEST_JSON_PATH = "test_action.json" From 221812fef2022c23918fc392819a1733e4166ae5 Mon Sep 17 00:00:00 2001 From: JeffreyChen Date: Sat, 25 Apr 2026 16:24:28 +0800 Subject: [PATCH 2/2] fix: replace module-name regex with str.isidentifier per-segment Semgrep flagged the compiled regex as a potential ReDoS pattern. Validating each dotted segment with str.isidentifier gives the same guarantee against shell/path payloads without any regex, removing the heuristic warning and reading more directly. --- .../utils/package_manager/package_manager_class.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/je_mail_thunder/utils/package_manager/package_manager_class.py b/je_mail_thunder/utils/package_manager/package_manager_class.py index 6a68814..f06e5a6 100644 --- a/je_mail_thunder/utils/package_manager/package_manager_class.py +++ b/je_mail_thunder/utils/package_manager/package_manager_class.py @@ -1,15 +1,14 @@ -import re from importlib import import_module from importlib.util import find_spec from inspect import getmembers, isfunction, isbuiltin, isclass from je_mail_thunder.utils.logging.loggin_instance import mail_thunder_logger -_MODULE_NAME_PATTERN = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)*$") - def _is_safe_module_name(package: str) -> bool: - return isinstance(package, str) and bool(_MODULE_NAME_PATTERN.fullmatch(package)) + if not isinstance(package, str) or not package: + return False + return all(part.isidentifier() for part in package.split(".")) class PackageManager: