From ba4546ecc9c06a5bcf18c10f366d1d91398e5a7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9CNaeel=E2=80=9D?= Date: Mon, 24 Aug 2026 20:07:23 +0300 Subject: [PATCH] =?UTF-8?q?v0.0.74:=20=D0=BE=D1=82=D0=BC=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=B2=20extract-=D1=84=D0=B0=D0=B7=D0=B5=20=E2=80=94=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B5=D1=80=D1=8B=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BD=D0=B5=20=D0=B6=D0=B4=D1=91=D1=82=20=D0=B2=D1=81=D0=B5=20?= =?UTF-8?q?.doc-=D0=BA=D0=BE=D0=BD=D0=B2=D0=B5=D1=80=D1=82=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- History/README.md | 1 + .../2026-08-24-v074-cancel-extract.md | 26 +++++++++++++++++++ drhider/obfuscator.py | 10 +++++-- site/app.py | 2 +- 4 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 History/code-fixes/2026-08-24-v074-cancel-extract.md diff --git a/History/README.md b/History/README.md index 0a0e774..315db4d 100644 --- a/History/README.md +++ b/History/README.md @@ -106,6 +106,7 @@ - **2026-08-24-time-tickers-estimates.md** — v0.0.64–0.0.65: тикер текущего файла на всех этапах, мгновенные оценки времени по файлам и суммарно. - **2026-08-24-folder-select-implemented.md** — v0.0.68: кнопка «Выбрать папку» (webkitdirectory, рекурсивно, относительный путь). - **2026-08-24-folder-zip-not-lost.md** — v0.0.69: архивы из папки без документов не теряются (добавляются как есть); раскрытие zip с документами; склонение счётчика. +- **2026-08-24-v074-cancel-extract.md** — v0.0.74: отмена в extract-фазе (не ждём все .doc). - **2026-08-24-v073-security-fixes.md** — v0.0.73: 6 фиксов по ревью Соннета (SSRF, path traversal, слабый SID, proc_error, zip-бомба, self-XSS); 1 отклонено (cleanup), 5 отложено. - **2026-08-24-pull-retry-limit-counter.md** — v0.0.72: ретраи pull из ВМ, корректная ошибка лимита сессии, счётчик дедупа. - **2026-08-24-code-review-sonnet.md** — код-ревью Соннета: 15 багов (SSRF, path traversal, слабый SID, zip-бомба и др.), промпт в docs/code-review-sonnet.md. diff --git a/History/code-fixes/2026-08-24-v074-cancel-extract.md b/History/code-fixes/2026-08-24-v074-cancel-extract.md new file mode 100644 index 0000000..faa36be --- /dev/null +++ b/History/code-fixes/2026-08-24-v074-cancel-extract.md @@ -0,0 +1,26 @@ +# v0.0.74 — отмена в extract-фазе (2026-08-24) + +_code-fixes. Доработка по код-ревью Соннета (пункт «отмена не работает в extract-фазе»)._ + +## Что сделано (`drhider/obfuscator.py`) +- В проходе 1 (извлечение) добавлена проверка `cancel_event.is_set()` между файлами: + при отмене цикл извлечения прерывается (`break`), LLM-сканирование пропускается, + результат помечается `cancelled` (processed=0, пустой ZIP + mapping.csv только заголовок). +- Раньше отмена ждала завершения ВСЕХ извлечений, включая медленные `.doc` (liberta, до 120с/файл). + +## Проверка +- `py_compile` — OK, `import` drhider — OK. +- Unit-тест: `cancel_event` установлен до старта → `meta={'cancelled': True, 'processed': 0, 'total': 2}`, + пустой ZIP (22 Б), CSV только заголовок. + +## Критично к Соннету (по итогам проверки) +- **«LLM-таймаут тихо обнуляет чанк»** — ОТКЛОНЕНО: `_call_llm` уже логирует + (`log.warning("LLM NER failed: %s", e)`) в `except Exception`. Таймаут не «тихий». +- **«cleanup после /download»** — ОТКЛОНЕНО ранее (ZIP и CSV скачиваются раздельно, см. v0.0.73). + +## Осталось (не трогаем, задокументировано) +- idx-мисматч `expand_zips` (фильтр расширений) — краевой случай, спорное поведение. +- LLM prompt injection — класс риска, не фикс кода. +- debug-эндпоинт `session_files` — мелочь, может сломать тесты. + +Версия 0.0.73 → 0.0.74. diff --git a/drhider/obfuscator.py b/drhider/obfuscator.py index 1b9385f..476a937 100644 --- a/drhider/obfuscator.py +++ b/drhider/obfuscator.py @@ -140,7 +140,13 @@ class TwoPassObfuscator: # Без параллельности: liberta не выдерживает конкурентные вызовы # (libreoffice падает с javaldx). + cancelled_extract = False for i, (fname, content, ctype) in enumerate(files): + # Мягкая остановка в фазе извлечения (между файлами) — не ждём все .doc + if cancel_event is not None and cancel_event.is_set(): + log.info("obfuscate: cancelled during extract, processed=%d/%d", i, total) + cancelled_extract = True + break display_name = os.path.basename(fname) or fname if progress_cb: progress_cb("start", i, total, display_name, 0.0) @@ -168,8 +174,8 @@ class TwoPassObfuscator: per_file={fname: len(t) for fname, t in all_texts.items()}) # LLM-сканирование (получает уже найденное regex'ом чтобы не дублировать) - cancelled_llm = False - if self._llm_client: + cancelled_llm = cancelled_extract + if not cancelled_llm and self._llm_client: try: scanner.scan_llm_ner( all_texts, self._mapping, self._llm_client, self._counters, diff --git a/site/app.py b/site/app.py index 97fbcea..c1b5d9f 100644 --- a/site/app.py +++ b/site/app.py @@ -21,7 +21,7 @@ if _sys_path_root not in sys.path: sys.path.insert(0, _sys_path_root) # Версия приложения (меняется при изменениях) -VERSION = "0.0.73" +VERSION = "0.0.74" def setup_logging():