fix: M2 word boundaries + L2 sorted_keys once (Opus review)
Deploy contracts-flask / validate (push) Successful in 0s

This commit is contained in:
2026-06-29 18:57:52 +04:00
parent 64a45a18bf
commit cb9eab38af
2 changed files with 24 additions and 10 deletions
+12 -5
View File
@@ -189,6 +189,7 @@ class TwoPassObfuscator:
def __init__(self, llm_client=None):
self._mapping: Dict[str, str] = {} # оригинал → замена (только для точных текстовых совпадений)
self._regex_replacements: List[Tuple[str, str, Callable]] = [] # (pattern, type, generator)
self._sorted_keys: List[str] = [] # ключи mapping, отсортированные по длине (убывание)
self._llm_client = llm_client
def obfuscate(self, files: List[Tuple[str, bytes, str]]) -> Tuple[bytes, str]:
@@ -220,6 +221,9 @@ class TwoPassObfuscator:
if self._llm_client:
self._scan_llm_ner(all_texts)
# Предсортировать ключи один раз для _apply_replacements
self._sorted_keys = sorted(self._mapping.keys(), key=len, reverse=True)
# --- Проход 2: замена ---
results = []
for fname, content, ctype in files:
@@ -244,6 +248,7 @@ class TwoPassObfuscator:
finally:
self._mapping.clear()
self._regex_replacements.clear()
self._sorted_keys.clear()
def _expand_zips(self, files: List[Tuple[str, bytes, str]]) -> List[Tuple[str, bytes, str]]:
"""Распаковать ZIP-файлы, заменив их содержимым. Остальные файлы — как есть."""
@@ -432,13 +437,15 @@ class TwoPassObfuscator:
def _apply_replacements(self, text: str) -> str:
"""Применить все замены из словаря mapping к строке. Сначала длинные, потом короткие."""
# Сортируем по длине оригинала (убывание) чтобы избежать частичных замен
sorted_keys = sorted(self._mapping.keys(), key=len, reverse=True)
result = text
for original in sorted_keys:
for original in self._sorted_keys:
replacement = self._mapping[original]
# Только точное совпадение (не подстрока)
result = re.sub(re.escape(original), replacement, result)
# Границы слова — если сущность начинается и заканчивается на \w
if original and original[0].isalnum() and original[-1].isalnum():
pattern = r'(?<!\w)' + re.escape(original) + r'(?!\w)'
else:
pattern = re.escape(original)
result = re.sub(pattern, replacement, result)
return result
# --- Сборка выдачи ---