fix: phone negative lookbehind, docx runs guard, 15 tests
Deploy contracts-flask / validate (push) Successful in 0s

This commit is contained in:
2026-06-29 18:26:54 +04:00
parent 2ebdaad2aa
commit 78f0e4d269
3 changed files with 165 additions and 98 deletions
+8 -4
View File
@@ -25,7 +25,7 @@ log = logging.getLogger("drhider")
# ═══════════════════════════════════════════
ENTITY_PATTERNS: Dict[str, str] = {
"phone": r'\b(?:\+7|8)[\s\-]?\(?\d{3}\)?[\s\-]?\d{3}[\s\-]?\d{2}[\s\-]?\d{2}\b',
"phone": r'(?<!\d)(?:\+7|8)[\s\-]?\(?\d{3}\)?[\s\-]?\d{3}[\s\-]?\d{2}[\s\-]?\d{2}(?!\d)',
"email": r'\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\b',
# 12-значный ИНН ДО 10-значного (иначе 12-значный матчится как 10)
"inn_fl": r'ИНН\s*\d{12}',
@@ -396,11 +396,13 @@ class TwoPassObfuscator:
# --- Проход 2: замена ---
def _replace_in_docx(self, doc) -> bytes:
"""Заменить сущности в docx-документе. Склеиваем runs → заменяем → пишем в первый run, остальные очищаем."""
"""Заменить сущности в docx. Склеиваем runs → заменяем → пишем в первый run, очищаем остальные."""
for para in doc.paragraphs:
if not para.runs:
continue
full_text = "".join(run.text for run in para.runs)
replaced = self._apply_replacements(full_text)
if replaced != full_text and para.runs:
if replaced != full_text:
para.runs[0].text = replaced
for run in para.runs[1:]:
run.text = ""
@@ -409,9 +411,11 @@ class TwoPassObfuscator:
for row in table.rows:
for cell in row.cells:
for para in cell.paragraphs:
if not para.runs:
continue
full_text = "".join(run.text for run in para.runs)
replaced = self._apply_replacements(full_text)
if replaced != full_text and para.runs:
if replaced != full_text:
para.runs[0].text = replaced
for run in para.runs[1:]:
run.text = ""