diff --git a/hb/resources/global_var.py b/hb/resources/global_var.py index 253ef0403a319215016bf030cf4011a6644e3e19..fba06b926ef3c04ccc9cf012d1edd958ec19d356 100644 --- a/hb/resources/global_var.py +++ b/hb/resources/global_var.py @@ -92,6 +92,28 @@ COMPONENTS_PATH_DIR = os.path.join(CURRENT_OHOS_ROOT, 'out/components_path.json' HPM_CHECK_INFO = "" +NINJA_DESCRIPTION = { + "ASM", + "CC", + "CXX", + "clang", + "clang++", + "cross compiler", + "gcc", + "iccarm", + "LLVM", + "OBJC", + "OBJCXX", + "AR", + "LINK", + "SOLINK", + "SOLINK_MODULE", + "RUST", + "ACTION", + "COPY", + "STAMP", +} + def set_hpm_check_info(info): global HPM_CHECK_INFO @@ -99,4 +121,4 @@ def set_hpm_check_info(info): def get_hpm_check_info(): - return HPM_CHECK_INFO \ No newline at end of file + return HPM_CHECK_INFO diff --git a/hb/util/log_util.py b/hb/util/log_util.py index 987fca57b28a9d0e2da1b669e4e6afdcadb6bf73..ca5d9aae786c6e649279775c278cf74a8afbd102 100755 --- a/hb/util/log_util.py +++ b/hb/util/log_util.py @@ -22,7 +22,7 @@ import os from containers.colors import Colors from hb.helper.no_instance import NoInstance -from resources.global_var import STATUS_FILE +from resources.global_var import STATUS_FILE, NINJA_DESCRIPTION from util.io_util import IoUtil from exceptions.ohos_exception import OHOSException @@ -160,7 +160,7 @@ class LogUtil(metaclass=NoInstance): is_ninja_failed = False with open(log_path, 'rt', encoding='utf-8') as log_file: data = log_file.read() - failed_pattern = re.compile(r'(ninja: error:.*?)\n', re.DOTALL) + failed_pattern = re.compile(r'(ninja: (?:error|fatal):.*?)\n', re.DOTALL) failed_log = failed_pattern.findall(data) if failed_log: is_ninja_failed = True @@ -180,14 +180,14 @@ class LogUtil(metaclass=NoInstance): is_compiler_failed = False with open(log_path, 'rt', encoding='utf-8') as log_file: data = log_file.read() - failed_pattern = re.compile( - r'(\[\d+/\d+\].*?)(?=\[\d+/\d+\]|' - 'ninja: build stopped)', re.DOTALL) + description_str = "|".join(re.escape(k) for k in NINJA_DESCRIPTION) + prefix = rf'(?:\[\d+/\d+\]\s+\b(?:{description_str}))\b' + failed_pattern = re.compile(rf'({prefix}.*?)(?={prefix}|ninja: build stopped)', re.DOTALL) failed_log = failed_pattern.findall(data) if failed_log: is_compiler_failed = True for log in failed_log: - if 'FAILED:' in log: + if any(line.startswith("FAILED:") for line in log.splitlines()): LogUtil.hb_error(log) with open(error_log, 'at', encoding='utf-8') as log_file: log_file.write(log) diff --git a/hb/util/system_util.py b/hb/util/system_util.py index 024ad19806de15bc67f0813b819facc5f7f339b7..ebe09cc88ebdc6d37d6410791c76ab2691428101 100755 --- a/hb/util/system_util.py +++ b/hb/util/system_util.py @@ -19,13 +19,15 @@ import os import re import subprocess +import copy from datetime import datetime +from resources.global_var import CURRENT_BUILD_DIR, CURRENT_OHOS_ROOT +from util.io_util import IoUtil from util.log_util import LogUtil from hb.helper.no_instance import NoInstance from containers.status import throw_exception -import copy class HandleKwargs(metaclass=NoInstance): @@ -106,6 +108,7 @@ class SystemUtil(metaclass=NoInstance): os.makedirs(os.path.dirname(log_path), exist_ok=True) HandleKwargs.before_msg(raw_kwargs) + hidden_pattern = SensitiveHidden.load_sensitive_conf() with open(log_path, 'at', encoding='utf-8') as log_file: process = subprocess.Popen(cmd, stdout=subprocess.PIPE, @@ -114,7 +117,8 @@ class SystemUtil(metaclass=NoInstance): env=exec_env, errors="ignore", **kwargs) - for line in iter(process.stdout.readline, ''): + for _line in iter(process.stdout.readline, ''): + line = SensitiveHidden.hidden_sensitive_info(hidden_pattern, _line) keep_deal, new_line = HandleKwargs.handle_line(line, raw_kwargs) if keep_deal: log_file.write(new_line) @@ -160,3 +164,64 @@ class ExecEnviron: if self._env is not None: allowed_env = {k: v for k, v in self._env.items() if k in allowed_vars} self._env = allowed_env + + +class SensitiveHidden: + @staticmethod + def determine_conf_file(): + config_file = os.path.join(CURRENT_BUILD_DIR, "sensitive_info_config.json") + sensitive_config_ext = os.path.join(CURRENT_OHOS_ROOT, "out/products_ext/sensitive_info_config.json") + if os.path.exists(sensitive_config_ext): + config_file = sensitive_config_ext + + return config_file + + @staticmethod + def parse_sensitive_conf(sensitive_config_file: str) -> set: + hidden_pattern = set() + + if not os.path.isfile(sensitive_config_file): + return hidden_pattern + + config = IoUtil.read_json_file(sensitive_config_file) + hidden_pattern.update(config.get("keywords", [])) + + for var_name in config.get("env_vars", []): + env_value = os.getenv(var_name) + if env_value: + hidden_pattern.add(env_value) + + for pattern_str in config.get("regex_patterns", []): + try: + # compile regex ignore case + hidden_pattern.add(re.compile(pattern_str, re.IGNORECASE)) + except re.error as e: + raise ValueError(f"invalid regex pattern '{pattern_str}': {e}") from e + + return hidden_pattern + + @staticmethod + def load_sensitive_conf() -> set: + config_file = SensitiveHidden.determine_conf_file() + + try: + hidden_pattern = SensitiveHidden.parse_sensitive_conf(config_file) + except Exception as e: + raise ValueError(f"{config_file} is invalid file, please check: {e}") from e + + return hidden_pattern + + @staticmethod + def hidden_sensitive_info(hidden_pattern: set, text: str, replace_text: str = "******") -> str: + if not hidden_pattern: + return text + hidden_text = text + for pattern in hidden_pattern: + if isinstance(pattern, str): + hidden_text = hidden_text.replace(pattern, replace_text) + elif isinstance(pattern, re.Pattern): + hidden_text = pattern.sub(replace_text, hidden_text) + else: + continue + + return hidden_text diff --git a/sensitive_info_config.json b/sensitive_info_config.json new file mode 100644 index 0000000000000000000000000000000000000000..6849ebf29a82590ef8d0e5a24aaef44592c6a33a --- /dev/null +++ b/sensitive_info_config.json @@ -0,0 +1,5 @@ +{ + "keywords": [], + "env_vars": [], + "regex_patterns": [] +}