fix(uninstall): preserve non-ASCII bytes when editing shell configs - #58271
fix(uninstall): preserve non-ASCII bytes when editing shell configs#58271nolanchic wants to merge 1 commit into
Conversation
remove_path_from_shell_configs() read/wrote ~/.bashrc, ~/.zshrc, etc. with
bare read_text()/write_text(), which decode/encode using the locale default
(cp1252 on Windows). The Windows installer explicitly supports Git Bash
(install.ps1 sets HERMES_GIT_BASH_PATH), and those users commonly have
non-ASCII bytes in their shell config (CJK comments, accented paths,
Powerline glyphs, emoji prompts). On Windows the bare calls either:
- raised UnicodeDecodeError → swallowed by the broad except → Hermes PATH
entries silently NOT removed (uninstall leaves junk behind); or
- decoded to wrong chars (many UTF-8 multibyte sequences are legal-but-
wrong in cp1252) → write_text() re-encoded the mojibake back,
permanently corrupting the user's shell config.
Read/write with encoding="utf-8", errors="surrogateescape" so the round-trip
is byte-for-byte lossless regardless of the file's encoding — the removed
PATH line is removed, everything else is preserved exactly.
Tests cover: a CJK .bashrc round-trips losslessly, a legacy ISO-8859 byte
survives, the pure-ASCII case still removes the line, an untouched file is
not rewritten, and a regression guard asserts the read/write pass an explicit
encoding. The Windows-default-encoding fixture (forces no-encoding reads/
writes to cp1252) lets the tests catch the bug on POSIX runners too;
verified they fail when the fix is reverted.
Closes no issue — found via cross-platform code audit (the bug is not in the
issue tracker).
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Comment (LGTM — token read-only, formal approval deferred to maintainer)
Fix for uninstall PATH cleanup silently skipping or corrupting shell configs on Windows due to locale-sensitive read_text/write_text. Uses encoding="utf-8", errors="surrogateescape" for a byte-for-byte lossless round-trip. Excellent test coverage including a windows_default_encoding monkeypatch fixture that simulates cp1252 on all platforms.
Looks Good
- Correct diagnosis: cp1252 decode fails or mojibakes; surrogateescape preserves bytes
- Test fixture covering cp1252 on POSIX runners catches the Windows bug during CI
- Covers CJK, ISO-8859, and emoji prompt scenarios
- Minimal change: only the encoding parameters, no structural rewrites
Reviewed by Hermes Agent
tonydwb
left a comment
There was a problem hiding this comment.
Code Review Summary
Verdict: Comment
Preserves non-ASCII bytes when editing shell configs during uninstall. Prevents corruption of locale-specific configurations.
Observations
- The fix reads the file as binary and edits byte-by-byte rather than as text — correct approach for preserving non-ASCII.
Looks Good
- No hardcoded secrets
- No debug artifacts
Reviewed by Hermes Agent
|
Thanks for the focused encoding fix. Current main still performs the locale-default read and rewrite at The proposed The target hunk has not moved since the PR base, and GitHub reports the branch mergeable; this should be a mechanical salvage. Automated hermes-sweeper review. |
|
Closing as resolved by PR #71078 (merged, commit d372fda), which retired the bare read_text/write_text class codebase-wide: 139 sites guarded (11 contributor PRs salvaged with authorship preserved — earliest submitters credited — plus an AST sweep), with a CI linter rule and AST guard test preventing regressions. Every site this PR touches is guarded on current main — verified per-site before closing. Thanks for the fix; the number of independent PRs on this class is what escalated it to the campaign. |
What
Fixes a shell-config corruption bug in
remove_path_from_shell_configs(): it read/wrote~/.bashrc,~/.zshrc, etc. with bareread_text()/write_text(), which use the locale default encoding (cp1252on Windows).Why it's a real bug (config corruption)
The Windows installer explicitly supports Git Bash (
scripts/install.ps1setsHERMES_GIT_BASH_PATH), andfind_shell_configs()has no platform guard — so on Windows,hermes uninstallgoes looking for~/.bashrc. Git Bash users commonly have non-ASCII bytes there: CJK comments, accented paths, Powerline glyphs, emoji prompts.With the bare
read_text()/write_text()(cp1252 on Windows), one of two things happens:UnicodeDecodeError→ swallowed by the broadexcept→ Hermes PATH entries silently NOT removed (uninstall leaves junk in the file).write_text()re-encodes the mojibake → the user's.bashrcis permanently corrupted. Their next shell session shows a garbled prompt.The fix
Read and write with
encoding="utf-8", errors="surrogateescape". This makes the round-trip byte-for-byte lossless regardless of the file's actual encoding: the hermes PATH line is removed, every other byte is preserved exactly.surrogateescaperound-trips undecodable bytes through the surrogate half, so even a legacy ISO-8859 file is edited safely.Why CI didn't catch it
scripts/check-windows-footguns.pyonly matchesopen(calls — it doesn't flagPath.read_text()/Path.write_text(). Same blindspot as the auth-store encoding fix in #58158 (that one is a separate PR/bug: different file, different data).How to test
pytest tests/hermes_cli/test_uninstall_bashrc_encoding.py -v # 5 passedTests cover:
.bashrcround-trips losslessly (hermes line removed, CJK preserved byte-for-byte)encoding=A
windows_default_encodingfixture forces a no-encodingread_text/write_textto use cp1252 (the Windows default), so the tests catch the bug on POSIX runners too. Verified all three encoding-sensitive tests fail when the fix is reverted.Platforms tested
macOS (Darwin 24.3.0, Python 3.11.15). The bug is Windows-specific (cp1252 locale default); the fix is a pure encoding-kwarg addition with
surrogateescape, which is no-op on POSIX for valid UTF-8 and lossless for everything else.check-windows-footguns.pypasses clean.Scope
One logical change: two lines in
hermes_cli/uninstall.py+ regression tests. No new dependencies, no core-file changes outsideuninstall.py.Related
Closes no issue — found via cross-platform code audit. Related encoding fix in #58158 (auth.json) — same bug class, different file/data, kept as separate PRs per "one logical change per PR".