Skip to content

refactor(utf8): убрать запись через перекодировку (#3826) - #3827

Open
kvirund wants to merge 3 commits into
masterfrom
kvirund/drop-koi8-writes
Open

kvirund wants to merge 3 commits into
masterfrom
kvirund/drop-koi8-writes

Conversation

@kvirund

@kvirund kvirund commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

Пункты 1 и 2 из #3826. Данные на диске — UTF-8, движок держит текст в UTF-8, переводить при
записи нечего.

Что убрано

Последняя запись в KOI8-R. craft.cpp заявлял в XML-декларации encoding="koi8-r"
и гнал байты через native_text::write_file. Теперь и декларация, и байты — UTF-8, как
у мира, cfg, state и userdata.

Сами функции. to_disk (вместе с предохранителем внутри неё), перекодирующий write_file
и мёртвая from_utf8 — ноль вызовов. write_file_native (3 вызова) переименован обратно
в write_file: отдельное имя было нужно, только пока рядом жил перекодирующий двойник.

Пароли: перекодировка осталась, но названа честно

password.cpp и accounts.cpp переведены на явный to_koi8. Перекодировка там нужна, но она
про формат сохранённых хэшей, а не про кодировку диска: хэши посчитаны по кои-восьмым байтам,
и сменить это можно только перехэшированием при успешном входе. Под именем to_disk это читалось
как граница диска, которой больше нет, — и напрашивалось на переиспользование.

Тест HashIsTakenOverTheOnDiskForm переименован и переписан под ту же мысль: свойство проверяется
то же самое (два разных набора байт с одной кои-восьмой формой дают один хэш), но перестало
называться «дисковой формой».

Что осталось

Граница чтения (from_disk_line / from_disk_text / read_data_file) — на месте: файл,
написанный до миграции, ещё может попасться. Её снятие вместе с исходящим предохранителем —
следующий шаг #3826, и вот он уже точка невозврата.

Тесты границы записи заменены тестом границы чтения — проверяет разделитель и его
идемпотентность. Заодно поправлены комментарии, ссылавшиеся на исчезнувшую функцию,
и шапка native_text.h, где диск всё ещё числился кои-восьмым.

Сборка без предупреждений, 691 тест проходит.

Данные на диске -- UTF-8, движок держит текст в UTF-8, переводить при записи нечего.

Последним местом, писавшим файл в KOI8-R, оставался craft.cpp: XML-декларация заявляла
encoding="koi8-r", и байты уходили через native_text::write_file. Теперь и декларация,
и байты -- UTF-8, как у мира, cfg, state и userdata.

Следом уходят сами функции: to_disk (вместе с предохранителем внутри неё), перекодирующий
write_file и мёртвая from_utf8 (ноль вызовов). write_file_native переименован обратно
в write_file -- отдельное имя было нужно, только пока рядом жил перекодирующий двойник.

Парольные вызовы переведены на явный to_koi8. Перекодировка там остаётся, но она про формат
СОХРАНЁННЫХ хэшей, а не про кодировку диска: хэши посчитаны по кои-восьмым байтам, и сменить
это можно только перехэшированием при успешном входе. Под именем to_disk это читалось как
граница диска, которой больше нет, и напрашивалось на переиспользование.

Заодно поправлены комментарии, ссылавшиеся на исчезнувшую функцию, и шапка native_text.h,
где диск всё ещё числился кои-восьмым.

Тесты границы записи заменены тестом границы чтения: она пока остаётся -- файл, написанный
до миграции, ещё может попасться. Её снятие -- следующий шаг #3826.
@bylins

bylins commented Sep 18, 2026

Copy link
Copy Markdown
Owner

Посмотрел ветку, пока она висит в draft. Слил её с нынешним master во временной ветке: конфликтов нет, собирается без предупреждений, 722 теста проходят (в master 723 — здесь два теста границы записи заменены одним тестом границы чтения).

По сути правка верная. to_disk для валидного UTF-8 просто вызывает to_koi8, так что замена в паролях на явный to_koi8 поведение не меняет, зато честнее называет: это формат старых хэшей, а не кодировка диска. Экспорт крафта теперь пишет encoding="utf-8" и UTF-8-байты, а старые выгрузки с объявлением koi8-r по-прежнему читаются — pugixml смотрит на объявление.

Два замечания.

1. Уходит предохранитель на записи. Вместе с to_disk исчезает её SYSERR «сюда пришли не те байты», который ловил пропущенную границу чтения. Сама граница чтения при этом остаётся, и в комментариях правки прямо сказано, что файл, написанный до миграции, ещё может попасться. Значит состояние, от которого предохранитель защищал, всё ещё возможно, а сигнала о нём больше не будет: кои-восьмые байты молча уедут в файл. Предлагаю оставить проверку внутри write_file — она недорогая, разбор строки идёт со скоростью порядка 477 МБ/с, а на записи файлов это тем более незаметно.

2. Мёртвая строка в glory_const.cpp:860. Там doc.append_attribute("encoding") = "koi8-r", но у xml_document атрибутов нет: в готовом lib/userdata/glory_const.xml стоит просто <?xml version="1.0"?>. Раз этот PR убирает последнее объявление koi8-r в записи (в craft.cpp), логично убрать заодно и эту строку.

Всё остальное чисто — из draft можно выводить.

bylins and others added 2 commits September 19, 2026 19:28
Вместе с to_disk уходил её предохранитель -- жалоба в лог, когда на
диск идут не-UTF-8 байты. Граница чтения при этом остаётся, и в
комментариях этой же ветки сказано, что файл, написанный до миграции,
ещё может попасться. Значит состояние, от которого предохранитель
защищал, всё ещё возможно, а сигнала о нём не было бы: кои-восьмые
байты уехали бы в файл молча. Проверка переехала в write_file.

glory_const писал в документ атрибут encoding="koi8-r", но у
xml_document атрибутов нет: в готовом файле стоит просто
<?xml version="1.0"?>. Строка мёртвая, а ветка как раз убирает
последнее объявление koi8-r в записи.

Заодно в ветку влит master: она отстала на две с лишним сотни коммитов.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bylins

bylins commented Sep 19, 2026

Copy link
Copy Markdown
Owner

Поправил по своему же разбору, раз добро получено:

  • предохранитель с записи не потерян — проверка на не-UTF-8 переехала из to_disk в write_file. Граница чтения остаётся, файл до миграции ещё может попасться, так что сигнал о пропущенной границе нужен; байты по-прежнему пишутся как есть, ломаться нечему;
  • убрана мёртвая строка doc.append_attribute("encoding") = "koi8-r" в glory_const.cpp: у xml_document атрибутов нет, в готовом файле стоит просто <?xml version="1.0"?>;
  • в ветку влит master — она отставала на 219 коммитов.

Сборка чистая, 722 теста проходят. PR всё ещё в draft — снимать статус вам.

@bylins
bylins marked this pull request as ready for review September 19, 2026 17:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants