Record rebased DM verification and UTF-8 name truncation defect

This commit is contained in:
evgeny committed 2026-10-26 17:07:18 +01:00
1 parent b6588d0594
commit f83e27260d
5 files changed
+84 -2

No files matched your search

+5
View File
@@ -57,6 +57,11 @@ AES-256-CCM: nonce 13 байт, tag 16 байт. Максимальная пор
Длительность ограничена 24 часами, размеры — 16384. Метаданные проверяются до
локального commit и до подтверждения получателем; S/M видят только ciphertext.
**Известный дефект снимка бесед (26.10.2026):** фиксированный `peer_name[64]`
усекает длинное корректное UTF-8-имя по байтам. Для 32 букв «Я» сохраняется
неполная последовательность без последнего байта, и JSON списка бесед с кодом успеха0
становится некорректным UTF-8. Подробности и план: [dm_audit_findings.txt](dm_audit_findings.txt), раздел8.
Медиа ciphertext — последовательность порций с отдельным tag каждой порции.
Последняя порция короче; пустой файл содержит один tag. Размер plaintext и SHA256
ciphertext должны входить в подписанный manifest. Потоковая расшифровка проверяет все
+61
View File
@@ -264,3 +264,64 @@ media-теста/native/sanitizer/контролей прочитаны;ожид
временная make-цель исправлена до контрольных прогонов. Основная сборка/код от этого не менялись.
Документация обновлена,задача quota-admission закрыта. Остальные отметки аудита DM остаются
частичными;GUI/Android/Windows/FreeBSD не запускались. Коммит/push не выполнялись.
7. Commit/rebase/push по запросу пользователя — 26.10.2026
Все накопленные изменения DM сохранены в2ae1990d. Fetch обнаружил8 новых коммитов
origin/master поверх03b05094:изменения headless PCM,документации звонков и их проверок.
Rebase на03be46c3 завершён с единственным конфликтом doc/tasks.md:сохранены обе
полные группы задач. tests/Makefile.am объединился автоматически,цели test_dm_load,
quota wrappers test_dm_media и upstream test_call_headless_queue присутствуют.
DM .c/.h и обе новые/расширенные регрессии побайтно сохранены относительно исходного коммита.
После rebase коммит стал b6588d059455ed430c902a325af7d010f15f3475.
Нативная сборка PASS;новый полный check.sh204/204 PASS,0 failed/0 skipped,
proxy9/9,burst1/1,load8/8 PASS,134217728 байт,exit0,175с. Включён новый upstream
test_call_headless_queue (11/11) и все DM-регрессии. Сеть — отдельный IPv6 namespace.
Push origin master:03be46c3..b6588d05 PASS,без force. git ls-remote подтвердил hash,
HEAD==origin/master,рабочее дерево после push было чистым.
Логи:/tmp/dm-audit-rebase-build.log,/tmp/dm-audit-rebase-full-check.log,
/tmp/dm-audit-rebase-netns.log. Санитайзеры после rebase заново не запускались;
исходные DM-файлы по сравнению с прошедшим sanitizer-профилем не менялись.
8. Продолжение: UTF-8 имя повреждается при построении беседы
Продолжены сверка core/history,передачи поколения и путей из attachment_send,
участков headless/GUI/JNI вызывающих функций. Это чтение кода,не аппаратная проверка UI.
Уточнён dm_send_file:0 означает вызов submit,который вправе синхронно вызвать callback
ошибки;результат подготовки сообщается событием. Это исправление описания возврата.
Новый подтверждённый дефект:dm_conv.peer_name[64],snprintf в dm_start/dm_conv_load
режут имя по63байтам,без проверки границы UTF-8. json_escape передаёт получившиеся
байты в JSON без проверки/исправления. Корректное входное имя тем самым повреждается
в SQLite,а dm_list_conversations_json возвращает0 с некорректным UTF-8 JSON.
dm_start_req допускает до127байт имени;отсутствует предусловие ASCII/<=63байт.
Стенд:/tmp/dm-utf8-audit.c/.mk. Настоящие core/chat_service/SQLite/X25519,
отдельные ключи для трёх собеседников,новая БД/tmp;публичные dm_start/list API.
Валидные входы:ASCII63байта;31×«Я»=62байта;32×«Я»=64байта.
Контроли ASCII63/UTF8_62 дают корректный UTF-8 JSON. UTF8_64 сохраняется как63байта,
последний байт0xd0 без продолжения;start=0,list=0. Строгий Python decode JSON
даёт invalid continuation byte на позиции537;проверка exit2. SQL-readonly-снимок
подтверждает тот же обрыв в сохранённом peer_name,tail_hex=afd0afd0afd0afd0.
Tracked allocations0->0;собственно C-стенд exit0,отказ обнаруживает независимый валидатор.
Сам runtime-лог тоже содержит этот некорректный байт:валидатор читает диагностический
лог с replacement только для поиска ASCII-путей,но JSON и SQL BLOB проверяет строго.
Причина однозначна по точным входным/сохранённым длинам и байтам;это не ошибка JSON
парсера,шифрования или вывода терминала. Повторная загрузка имени через dm_conv_load
имеет то же побайтовое усечение;этот путь в новом стенде отдельно не запускался.
Простой план:определить единое ограничение имени и копировать только целые UTF-8
code points. Проверять входы и уже сохранённые некорректные строки с диагностикой;
увеличение массива само по себе не решает обрыв на новой границе.
Постоянные проверки:ASCII и2/3/4-байтовые символы до/на/за границей,SQL round-trip,
повторная загрузка и строгая декодируемость JSON. До выбора обработки уже повреждённых
имён (безопасное усечение/отказ) рабочая реализация не менялась.
Логи:/tmp/dm-utf8-audit-build.log,/tmp/dm-utf8-audit-runtime.log,
/tmp/dm-utf8-audit-validation.log;валидатор:/tmp/dm-utf8-audit-validate.py.
По AGENTS.md:10 дальнейший аудит остановлен,задача открыта в doc/tasks.md.
В продолжении только комментарии/документы,все текущие частичные отметки сохранены.
Предыдущий check204 проверял объединённые исправления,а не обработку нового имени;
новые sanitizer/GUI/Android/Windows/FreeBSD проверки не запускались.
+10
View File
@@ -4,6 +4,16 @@
## Текущие задачи
[ ] **DM: сохранять границы UTF-8 при усечении имени собеседника** — подтверждено 26.10.2026.
dm_start и dm_conv_load копируют имя через snprintf в peer_name[64],json_escape не проверяет UTF-8.
Валидные64байта (32×«Я») сохраняются как63байта с оборванным0xd0;start/list возвращают0,
строгий decode UTF-8 JSON даёт invalid continuation byte. ASCII63 и UTF8_62 — PASS;allocations0->0.
Нужен единый контракт UTF-8 копирования при сохранении/загрузке:усечение только целых code points,
обработка уже некорректных сохранённых имён с диагностикой,границы двух/трёх/четырёхбайтовых символов.
Увеличение буфера само по себе проблему не устраняет. Стенд /tmp/dm-utf8-audit.c/.mk,
логи /tmp/dm-utf8-audit-{build,runtime,validation}.log. Аудит остановлен по AGENTS.md:10.
Подробности: [dm_audit_findings.txt](dm_audit_findings.txt),раздел8. Production/тесты в этом этапе не менялись.
[ ] **Android call mute: передавать настоящий PCM и флаг mute через JNI до core** — подтверждено 26.10.2026.
CallAudioEngine.captureLoop заменяет микрофон тишиной до nativeCallAudioFeed; bridge вызывает feed_pcm.
Включённый AEC после этого снова создаёт ненулевой сигнал перед Opus. Стенд с настоящими bridge/Opus/AEC,
+3 -1
View File
@@ -103,7 +103,9 @@ void dm_delete_trampoline(void* arg);
void dm_cancel_pending_history(struct UTUN_INSTANCE* inst, const char* conv);
/* До 200 видимых бесед по last_ts DESC: [{conv_id,peer_node_id,peer_name,last_ts,out_seq,in_seq,generation}].
* buf вмещает JSON и NUL; 0 и *out_len без NUL при успехе, -1 при ошибке. Все вызовы в uasync. */
* buf вмещает JSON и NUL; 0 и *out_len без NUL при успехе, -1 при ошибке. Все вызовы в uasync.
* Известный дефект: имя может быть обрезано внутри UTF-8 в dm_start/load, и результат с кодом0 будет
* некорректным UTF-8 JSON. См. doc/dm_audit_findings.txt, раздел8. */
int dm_list_conversations_json(struct UTUN_INSTANCE* inst, char* buf, size_t buf_size, size_t* out_len);
/* Сообщения беседы в JSON: расшифрованное содержимое, статусы доставки и медиа.
+5 -1
View File
@@ -33,7 +33,11 @@ int dm_media_init(struct UTUN_INSTANCE* inst);
void dm_media_quiesce(struct UTUN_INSTANCE* inst);
void dm_media_destroy(struct UTUN_INSTANCE* inst);
/* Подготовить копию и enqueue file-сообщение асинхронно. 0=задача принята. */
/* Передать подготовку копии и enqueue file-сообщения в media_async.
* Строки conv/path и info копируются при вызове; сам файл должен быть доступен worker до завершения.
* 0=submit вызван, -1=отказ до submit. Submit может синхронно завершиться ошибкой через callback;
* готовность/ошибка подготовки сообщается CHAT_EVT_ATTACHMENT_PREPARATION, включая до возврата0.
* remove_source=1 передаёт worker собственный временный файл приложения для удаления; при -1 его убирает caller. */
int dm_send_file(struct UTUN_INSTANCE* inst, const char* conv, const char* path, const struct attachment_info* info,
int remove_source);
struct dm_file_req {