from __future__ import annotations import os import re SENSITIVE_KEYS = ( "pub_key", "signature", "key_b64", "flash_key_b64", "sig_b64", "pub_key_jkt", "new_pub_key", "new_pub_key_jkt", "device_mac", "operator", "host", "port", "firmware_version", ) _ANSI_RE = re.compile(r"\x1b\[[0-9;]*[A-Za-z]") _MAC_RE = re.compile(r"(?i)([0-9a-f]{2}:){5}[0-9a-f]{2}") _UUID_RE = re.compile( r"\b[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}\b" ) _URL_RE = re.compile(r"https?://[^\s]+") _DEVICE_ID_JSON_RE = re.compile(r'("device_id"\s*:\s*")([^"]+)(")', re.IGNORECASE) _DEVICE_ID_KV_RE = re.compile(r"(\bdevice_id\b\s*[:=]\s*)([^\s,;]+)", re.IGNORECASE) _JSON_KEY_RE = re.compile( r'([\'"](?:(?:' + "|".join(SENSITIVE_KEYS) + r'))[\'"]\s*:\s*[\'"])([^\'"]+)([\'"])', re.IGNORECASE, ) _KV_RE = re.compile(r"(?i)\b(" + "|".join(SENSITIVE_KEYS) + r")=([^\s,;]+)") _HEX_BYTES_RE = re.compile(r"\b(?:[0-9a-fA-F]{2}\s+){7,}[0-9a-fA-F]{2}\b") _BIN_PATH_RE = re.compile(r"(/[^\\s]+?\\.(?:bin(?:\\.enc)?|enc))") _BIN_NAME_RE = re.compile(r"\b[\w.-]+\\.(?:bin(?:\\.enc)?|enc)\b") def _sanitize_filename(value: str) -> str: if not value: return "unknown" return re.sub(r"[^A-Za-z0-9._-]+", "_", value) def _preserve_device_ids(text: str) -> tuple[str, dict[str, str]]: tokens: dict[str, str] = {} def _tokenize(value: str) -> str: token = f"__DEVICE_ID_{len(tokens)}__" tokens[token] = value return token def _replace_json(match: re.Match[str]) -> str: return f"{match.group(1)}{_tokenize(match.group(2))}{match.group(3)}" def _replace_kv(match: re.Match[str]) -> str: return f"{match.group(1)}{_tokenize(match.group(2))}" text = _DEVICE_ID_JSON_RE.sub(_replace_json, text) text = _DEVICE_ID_KV_RE.sub(_replace_kv, text) return text, tokens def _redact_sensitive(text: str) -> str: if not text: return text text, device_tokens = _preserve_device_ids(text) text = _ANSI_RE.sub("", text) text = _MAC_RE.sub("", text) text = _UUID_RE.sub("", text) text = _URL_RE.sub("", text) text = _JSON_KEY_RE.sub( lambda m: f"{m.group(1)}{m.group(3)}", text ) text = _KV_RE.sub( lambda m: f"{m.group(1)}=", text ) text = _HEX_BYTES_RE.sub("", text) text = _BIN_PATH_RE.sub(lambda m: os.path.basename(m.group(1)), text) text = _BIN_NAME_RE.sub("", text) lowered = text.lower() if "security features enabled" in lowered: return "检测到限制,保持默认配置。" if "compress and encrypt options are mutually exclusive" in lowered: return "写入选项冲突,已使用默认方式。" if "will flash input bytes uncompressed" in lowered: return "将按默认方式写入。" if "cannot verify written data" in lowered: return "写入完成,校验已跳过。" if "secure boot detected" in lowered or "secure download mode is enabled" in lowered: return "检测到写入限制,请按工艺选择模式。" for token, value in device_tokens.items(): text = text.replace(token, value) return text