fix(v2): set LANG for pbpaste/pbcopy to prevent clipboard mojibake on macOS#5012
fix(v2): set LANG for pbpaste/pbcopy to prevent clipboard mojibake on macOS#5012veeceey wants to merge 2 commits intowailsapp:masterfrom
Conversation
When macOS apps are launched as standalone (not from terminal), the LANG environment variable is unset. This causes pbpaste to default to an ASCII-compatible encoding, resulting in mojibake for non-ASCII clipboard content. Fix by ensuring LANG=en_US.UTF-8 is set in the command environment when it's not already present. Fixes wailsapp#4132
Manual test results (macOS 15, M4)Verified the fix works by testing pbpaste behavior with and without LANG: Also confirmed that |
📝 WalkthroughWalkthroughAdds an ensureUTF8Env helper and applies it to the pbpaste and pbcopy command environments so macOS clipboard reads/writes run with LANG set to en_US.UTF-8 when LANG is unset. Changes
Estimated code review effort🎯 2 (Simple) | ⏱️ ~8 minutes Possibly related issues
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 OpenGrep (1.16.0)v2/internal/frontend/desktop/darwin/clipboard.go┌──────────────┐ �[32m✔�[39m �[1mOpengrep OSS�[0m �[1m Loading rules from local config...�[0m Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
v2/internal/frontend/desktop/darwin/clipboard.go (1)
14-22: Consideros.LookupEnvfor a cleaner, more idiomatic implementation.
os.LookupEnvexplicitly distinguishes "not set" from "set to empty" without manual string slicing, and is the standard Go idiom for this pattern:♻️ Proposed refactor
func ensureUTF8Env() []string { env := os.Environ() - for _, e := range env { - if len(e) > 5 && e[:5] == "LANG=" { - return env - } + if _, ok := os.LookupEnv("LANG"); !ok { + env = append(env, "LANG=en_US.UTF-8") } - return append(env, "LANG=en_US.UTF-8") + return env }This also correctly handles the case where
LANGis set but empty (keeping the existing empty value rather than creating a duplicate entry), which the current loop misses due to the> 5boundary.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@v2/internal/frontend/desktop/darwin/clipboard.go` around lines 14 - 22, Replace the manual loop in ensureUTF8Env with os.LookupEnv: use os.LookupEnv("LANG") to detect whether LANG is present (allowing an existing empty value to be preserved) and, if not present, append "LANG=en_US.UTF-8" to os.Environ(); ensure you return the original env unchanged when LANG is set (including empty string) to avoid duplicating entries and to follow Go idioms.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@v2/internal/frontend/desktop/darwin/clipboard.go`:
- Line 17: The guard that checks environment entries uses len(e) > 5 && e[:5] ==
"LANG=" which misses the exact "LANG=" entry; update the check in the loop over
environment entries (the variable e) to use a correct boundary such as len(e) >=
5 && e[:5] == "LANG=" or, better, strings.HasPrefix(e, "LANG=") so entries equal
to "LANG=" are treated as matches and the function will early-return instead of
appending a second LANG variable.
---
Nitpick comments:
In `@v2/internal/frontend/desktop/darwin/clipboard.go`:
- Around line 14-22: Replace the manual loop in ensureUTF8Env with os.LookupEnv:
use os.LookupEnv("LANG") to detect whether LANG is present (allowing an existing
empty value to be preserved) and, if not present, append "LANG=en_US.UTF-8" to
os.Environ(); ensure you return the original env unchanged when LANG is set
(including empty string) to avoid duplicating entries and to follow Go idioms.
Replace manual string slicing with os.LookupEnv which is more idiomatic and correctly handles the edge case where LANG is set to an empty string.
There was a problem hiding this comment.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@v2/internal/frontend/desktop/darwin/clipboard.go`:
- Around line 14-20: The function ensureUTF8Env correctly uses
os.LookupEnv("LANG") to detect presence (including an empty LANG=) and only
appends "LANG=en_US.UTF-8" when absent, so no code change is required; keep the
current implementation (ensureUTF8Env) as-is and approve the change.
Fixes #4132
When a Wails app runs as a standalone macOS app (not launched from a terminal), the
LANGenvironment variable is unset.pbpastethen defaults to an ASCII-compatible encoding, which turns non-ASCII clipboard content into garbage.The fix ensures
LANG=en_US.UTF-8is set in the command's environment before invokingpbpaste/pbcopy, but only whenLANGisn't already present — so it won't override anything the user has explicitly set.Quick terminal demo showing the difference:
Summary by CodeRabbit