fix: drhider _build_zip — ZipInfo UTF-8 flag for Cyrillic filenames (v1.7)
Deploy contracts-flask / validate (push) Successful in 0s

This commit is contained in:
2026-07-07 15:34:36 +04:00
parent 78c5503cfd
commit 54be17dad5
5 changed files with 36 additions and 4 deletions
+28
View File
@@ -0,0 +1,28 @@
# DrHider — Cyrillic filenames in ZIP fix (2026-07-07)
## Проблема
Кириллические имена файлов в выходном ZIP отображаются кракозябрами
(CP437 вместо UTF-8). Содержимое файлов — OK.
## Причина
`zipfile.ZipFile` в режиме записи кодирует имена в CP437.
Python 3.12 `metadata_encoding='utf-8'` работает **только на чтение**,
при записи → `ValueError`.
## Решение
Использовать `ZipInfo` с флагом UTF-8 (бит 11 = 0x800):
```python
# Было:
zf.writestr(fname, content)
# Стало:
info = zipfile.ZipInfo(fname)
info.flag_bits |= 0x800
zf.writestr(info, content)
```
## Затронутые файлы
- ВМ: `/home/naeel/contracts/drhider/drhider.py``_build_zip`
- `contracts-flask/deploy/drhider/drhider.py`
- `contracts-flask/site/services/drhider.py`
+3 -1
View File
@@ -466,7 +466,9 @@ class TwoPassObfuscator:
buf = io.BytesIO()
with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zf:
for fname, content in files:
zf.writestr(fname, content)
info = zipfile.ZipInfo(fname)
info.flag_bits |= 0x800 # UTF-8 filename
zf.writestr(info, content)
if mapping_csv:
zf.writestr("mapping.csv", '\ufeff'.encode('utf-8') + mapping_csv.encode('utf-8'))
return buf.getvalue()
+3 -1
View File
@@ -458,7 +458,9 @@ class TwoPassObfuscator:
buf = io.BytesIO()
with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zf:
for fname, content in files:
zf.writestr(fname, content)
info = zipfile.ZipInfo(fname)
info.flag_bits |= 0x800 # UTF-8 filename
zf.writestr(info, content)
if mapping_csv:
zf.writestr("mapping.csv", '\ufeff'.encode('utf-8') + mapping_csv.encode('utf-8'))
return buf.getvalue()
+1 -1
View File
@@ -84,7 +84,7 @@
<a href="https://contractor.pythonk8s.services.ngcloud.ru/">Сверка договоров</a>
<span class="sep">|</span>
<strong>DrHider</strong>
<span style="font-size:11px;color:var(--muted);">v1.6</span>
<span style="font-size:11px;color:var(--muted);">v1.7</span>
<button class="help-btn" onclick="openModal()" title="О сервисе">?</button>
</header>
+1 -1
View File
@@ -73,7 +73,7 @@
<body>
<div class="topbar">
<img src="/static/logo.svg" alt="Nubes">
<span class="title">Сверка договоров — LLM AI-driven Event Sourcing <span style="font-weight:400;color:var(--muted);font-size:12px;">v1.0.193-flask</span></span>
<span class="title">Сверка договоров — LLM AI-driven Event Sourcing <span style="font-weight:400;color:var(--muted);font-size:12px;">v1.0.194-flask</span></span>
<div id="pipelineStepper" style="display:flex;gap:8px;font-size:11px;align-items:center;color:var(--muted);">
<span id="stepUpload">○ Загрузка</span><span></span>
<span id="stepClassify">○ Классификация</span><span></span>