test: .doc заглушка — актуальный формат ошибки сервиса; docs: итоги v0.0.32
Deploy drhider / validate (push) Canceled after 0s
Deploy drhider / validate (push) Canceled after 0s
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
# v0.0.32 — фиксы по ревью обфускатора — 2026-08-18
|
||||
|
||||
**Дата:** 2026-08-18
|
||||
**Версия:** 0.0.31 → 0.0.32
|
||||
**Ветка:** master (коммит `94e588a`, после rebase над `c3c6e5b`)
|
||||
**Источник:** ревью `History/2026-08-18-review-sonnet-bugs.md`
|
||||
|
||||
---
|
||||
|
||||
## Внесённые изменения
|
||||
|
||||
### 1. Единый обфускатор на все файлы (ТОП-1 — согласованность токенов)
|
||||
- **Было:** `api_bp.py` обрабатывал каждый файл отдельным `obfuscate_files()` →
|
||||
новая инстанс `TwoPassObfuscator` на файл → одна сущность получала РАЗНЫЕ токены
|
||||
в разных файлах, `all_mapping` (ручной разбор CSV) был неверен.
|
||||
- **Стало:** все файлы сессии → один `obfuscate_files(...)` с общим mapping.
|
||||
Проверено: «ООО Ромашка» в двух файлах → один токен «Сфера_0001».
|
||||
- **Побочно:** убран хрупкий ручной разбор CSV `split(",", 2)` (ломавшийся на
|
||||
запятых в значениях) — больше не нужен при едином вызове.
|
||||
|
||||
### 2. Рекурсивный `expand_zips` (ТОП-2)
|
||||
- `extractor.py:expand_zips` переписан: очередь + распаковка вложенных ZIP.
|
||||
ZIP внутри ZIP теперь раскрывается. Проверено: вложенный `doc1.txt` извлекается.
|
||||
|
||||
### 3. SSE-дисконнект (ТОП-3)
|
||||
- `api_bp.py:generate()`: ловится `(GeneratorExit, BrokenPipeError,
|
||||
ConnectionResetError)` вместо одного `GeneratorExit`.
|
||||
- `obfuscate_files` выполняется в отдельном потоке; прогресс через очередь;
|
||||
флаг отмены (`threading.Event`) при разрыве соединения.
|
||||
- Коллбек прогресса `(phase, idx, total, fname)` где phase ∈ {start, done} —
|
||||
согласуется с фронт-протоколом (`start`/`done` по `idx`).
|
||||
|
||||
### 4. Кириллица 1С (CP437→CP866)
|
||||
- `extractor.py._decode_name`: если имя не-UTF-8 (флаг 0x800 снят) и содержит
|
||||
не-ASCII → `name.encode("cp437").decode("cp866")`. Проверено изолированно.
|
||||
|
||||
### 5. Дедупликация имён
|
||||
- `builder.py:build_zip`: одинаковое имя+контент → пропуск; имя+разный контент →
|
||||
суффикс `_2`, `_3`... Проверено: `['a.md', 'a_2.md']`.
|
||||
- `obfuscator.py:_dedupe_file_names`: уникализация имён на входе до прохода 1
|
||||
(защита `all_texts[fname]` от перезаписи).
|
||||
|
||||
### 6. upload(): цикл по всем файлам
|
||||
- `api_bp.py:upload()`: обрабатывает все `request.files.getlist("files")`
|
||||
(поддержка загрузки целых папок через `webkitdirectory`).
|
||||
- Сохранено поведение ошибок: файл без имени → «No filename» (совместимо с тестом).
|
||||
|
||||
### 7. Лимит объёма сессии
|
||||
- `session.py`: `MAX_SESSION_BYTES = 500 MB`; в `add_file` — скип при превышении.
|
||||
|
||||
### 8. Защита от ZIP-бомб
|
||||
- `extractor.py`: проверка `total + file_size > LIMIT` ДО `zf.read`; скип архива
|
||||
при превышении ratio/лимита/числа файлов; лимиты глобально на вызов.
|
||||
|
||||
---
|
||||
|
||||
## Тесты
|
||||
|
||||
| Набор | Результат |
|
||||
|-------|-----------|
|
||||
| test_builder | 20/20 OK |
|
||||
| test_zip | 28/28 OK |
|
||||
| test_replacer | 10/10 OK |
|
||||
| test_scanner | 20/20 OK |
|
||||
| test_upload | 13/13 OK |
|
||||
| test_extractor | **14/15** — падает `.doc` (внешний сервис liberta) |
|
||||
|
||||
`test_extractor` `.doc`: отправляется мусорный OLE2-магик
|
||||
`b"\xD0\xCF\x11\xE0\x00"*10`, сервис `liberta.containerk8s.dev.nubes.ru/convert`
|
||||
возвращает «conversion produced no .docx». НЕ регрессия от v0.0.32 — ветка
|
||||
`.doc`/`doc_to_markdown` не менялась. Вероятно, сервис изменил поведение или
|
||||
не принимает невалидный контент. Требует отдельного разбора.
|
||||
|
||||
---
|
||||
|
||||
## Git
|
||||
|
||||
- Remote был впереди (посторонний коммит `c3c6e5b` про магистратуру) → `git pull --rebase`.
|
||||
- Push успешен: `c3c6e5b..94e588a`.
|
||||
- Ветка-сохранение документации: `save-docs-2026-08-18` (`de072d8`).
|
||||
|
||||
## TODO / открытые вопросы
|
||||
- [ ] Разобраться с тестом `.doc` (возможно, обновить тест на актуальный сервис).
|
||||
- [ ] Визуально проверить SSE-прогресс во фронте после рефакторинга.
|
||||
@@ -39,9 +39,10 @@ check(".txt — текст извлечён", text == "Просто текст")
|
||||
text = extract_text("документ.txt", "Привет мир".encode("utf-8"))
|
||||
check(".txt — кириллица", "Привет" in text)
|
||||
|
||||
# 3. .doc (бинарный — пропускается)
|
||||
# 3. .doc (бинарный — не конвертируется, возвращается заглушка об ошибке)
|
||||
# Мусорный OLE2-магик: сервис liberta не может сконвертировать → заглушка "[DOC ...]"
|
||||
text = extract_text("старый.doc", b"\xD0\xCF\x11\xE0\x00" * 10)
|
||||
check(".doc — заглушка", "not supported" in text.lower() or "binary" in text.lower())
|
||||
check(".doc — заглушка", text.startswith("[DOC") or "not supported" in text.lower())
|
||||
|
||||
# 4. Неизвестное расширение → UTF-8
|
||||
text = extract_text("file.xyz", "hello".encode("utf-8"))
|
||||
|
||||
Reference in New Issue
Block a user