Skip to content

Windows: fix non-ASCII chat prompt corruption (ANSI codepage vs UTF-8)#366

Merged
JustVugg merged 1 commit into
JustVugg:mainfrom
vologn4mor:fix/win-utf8-prompt-env
Jul 19, 2026
Merged

Windows: fix non-ASCII chat prompt corruption (ANSI codepage vs UTF-8)#366
JustVugg merged 1 commit into
JustVugg:mainfrom
vologn4mor:fix/win-utf8-prompt-env

Conversation

@vologn4mor

Copy link
Copy Markdown
Contributor

Summary

  • On native Windows, coli run/coli chat pass the prompt to glm.exe through the PROMPT/COLI_PROMPT environment variable. Plain getenv() there is populated by the CRT from the ANSI codepage view of the environment block, not UTF-8 — so any non-ASCII prompt text (Cyrillic, CJK, ...) gets silently mangled before the byte-level tokenizer ever sees it, even though coli's Python subprocess call sets the value correctly through the wide (UTF-16) environment block.
  • Adds compat_getenv_utf8() in compat.h: reads the variable via GetEnvironmentVariableW and converts straight to UTF-8, bypassing the ANSI codepage entirely. No-op passthrough to getenv() on non-Windows platforms — zero impact there.
  • coli_user_prompt() in glm.c now uses it for both COLI_PROMPT and PROMPT.

How I found it

Ran a fresh Windows 11 native build/install per the README and hit this while testing coli run with a Russian prompt: both the echoed input and the generated output came back as replacement-character garbage. Traced it to the env-var read path in coli_user_prompt() (glm.c) — narrow getenv() round-tripping non-ASCII text through the system ANSI codepage.

Test plan

  • Rebuilt glm.exe (MinGW-w64, gcc 16.1.0) with the fix.
  • Tiny-oracle self-test still passes 32/32 after rebuild (no regression).
  • Ran the full GLM-5.2-int4 model with a Cyrillic prompt ("Привет! Кто ты?"): before the fix, input echo and output were both garbled; after the fix, the prompt round-trips intact and the model produces coherent Cyrillic output end to end.
  • Non-Windows platforms unaffected (getenv_utf8 is a plain getenv() alias outside _WIN32).

coli passes the chat prompt to glm.exe through the PROMPT/COLI_PROMPT
environment variable. On Windows, plain getenv() is populated by the CRT
from the ANSI-codepage view of the environment block, not UTF-8 — so any
non-ASCII prompt text (Cyrillic, CJK, ...) is silently mangled before the
byte-level tokenizer ever sees it, even though the parent process (coli's
Python subprocess call) sets the value correctly via the wide env block.

Add compat_getenv_utf8() in compat.h: reads the variable through
GetEnvironmentVariableW and converts straight to UTF-8, bypassing the ANSI
codepage entirely. No-op passthrough to getenv() on non-Windows platforms.
coli_user_prompt() in glm.c now uses it for both COLI_PROMPT and PROMPT.

Verified: tiny-oracle self-test still 32/32 after rebuild, and a real run
against the full GLM-5.2-int4 model with a Cyrillic prompt now round-trips
correctly end to end (input echoed intact, coherent Cyrillic output),
where it previously produced replacement-character garbage on both input
and output.
JustVugg added a commit that referenced this pull request Jul 19, 2026
fix(test): make test_stops build on Windows (mkdtemp compat shim)

Conflict with #366's getenv_utf8 in compat.h resolved by keeping both blocks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@JustVugg JustVugg mentioned this pull request Jul 19, 2026
@JustVugg
JustVugg merged commit e5b1e19 into JustVugg:main Jul 19, 2026
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