Skip to content

fix(status): walk the argument by characters, not by bytes - #3795

Merged
bylins merged 1 commit into
masterfrom
fix/status-custom-utf8
Aug 29, 2026
Merged

fix(status): walk the argument by characters, not by bytes#3795
bylins merged 1 commit into
masterfrom
fix/status-custom-utf8

Conversation

@bylins

@bylins bylins commented Aug 29, 2026

Copy link
Copy Markdown
Owner

статус все и статус нет работают, а свой набор букв поставить нельзя — команда печатает справку и ничего не меняет.

Почему

Первые два варианта разбираются через str_cmp до цикла, поэтому они и работали. Свой набор разбирался побайтно:

const size_t len = strlen(argument);
for (size_t i = 0; i < len; i++) {
    switch (native_text::first_char_code_lower(argument + i)) {

Под UTF-8 русская буква занимает два байта. После каждой буквы шаг в один байт приводил к её хвостовому байту — он не совпадает ни с одной меткой и уводит разбор в default, то есть в справку и return. На модели видно наглядно:

посимвольно      -> ['ж', 'з', 'в']
побайтно (как было) -> ['ж', '?мусор?', 'з', '?мусор?', 'в', '?мусор?']

Латиница из одного байта при этом работала: статус hw ставил флаги как надо. Отсюда и вид бага — «русские буквы не принимаются».

Что сделано

Шаг по символу, native_text::char_bytes. Для однобайтовых букв это тот же шаг на единицу, так что латиница ведёт себя как раньше. Функция всегда возвращает не меньше единицы, зациклиться цикл не может.

Тест

tests/status.command.cpp: кириллический набор (жзв → жизнь, запас сил, выходы), латиница (hw) и поведение при неизвестной букве — разбор обрывается, а применённое до неё остаётся; это как было, тест просто фиксирует.

Без правки падает ровно тест с кириллицей, два других проходят в обоих случаях. Полный прогон — 672 теста зелёные.

До выката

Обходной путь для игроков — латинские буквы: статус жзв = статус hwe.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XUwDWDnYdXrJdvjDVd36QH

"статус все" и "статус нет" работали, а свой набор букв поставить было нельзя:
команда печатала справку и ничего не меняла.

Аргумент разбирался побайтно, а под UTF-8 русская буква занимает два байта.
После каждой буквы шаг в один байт приводил к её хвостовому байту: он не
совпадал ни с одной меткой и уводил разбор в default. Латиница из одного байта
при этом работала, поэтому со стороны выглядело как "русские буквы не
принимаются".

Шаг теперь по символу -- native_text::char_bytes. Для однобайтовых букв это тот
же шаг на единицу, так что латиница ведёт себя как раньше.

Тест: tests/status.command.cpp -- кириллический набор, латиница и поведение при
неизвестной букве (разбор обрывается, применённое до неё остаётся).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUwDWDnYdXrJdvjDVd36QH
@bylins
bylins merged commit 82f434a into master Aug 29, 2026
20 checks passed
@bylins
bylins deleted the fix/status-custom-utf8 branch August 29, 2026 11:08
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.

1 participant