mirror of
https://github.com/instructkr/claw-code.git
synced 2026-10-27 00:00:00 +08:00
fix(runtime): skip non-UTF-8 environment variables instead of panicking (#3356)
std::env::vars() panics on any non-UTF-8 value. zsh exports a metafied $_ when the command path contains non-ASCII characters (e.g. 下載), so claw panicked on startup. Use vars_os() and skip entries that are not valid UTF-8.
This commit is contained in:
1 parent
917a9e28ee
commit
c55c7e4710
3 files changed
+45
-3
No files matched your search
@@ -66,7 +66,7 @@ pub struct UpstreamProxyState {
|
||||
impl RemoteSessionContext {
|
||||
#[must_use]
|
||||
pub fn from_env() -> Self {
|
||||
Self::from_env_map(&env::vars().collect())
|
||||
Self::from_env_map(&utf8_env_map())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
@@ -89,7 +89,7 @@ impl RemoteSessionContext {
|
||||
impl UpstreamProxyBootstrap {
|
||||
#[must_use]
|
||||
pub fn from_env() -> Self {
|
||||
Self::from_env_map(&env::vars().collect())
|
||||
Self::from_env_map(&utf8_env_map())
|
||||
}
|
||||
|
||||
#[must_use]
|
||||
@@ -234,6 +234,16 @@ pub fn inherited_upstream_proxy_env(
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Snapshot of the process environment, skipping non-UTF-8 entries.
|
||||
///
|
||||
/// `env::vars()` panics on non-UTF-8 values (e.g. zsh exports a metafied `$_`
|
||||
/// when the command path contains non-ASCII characters).
|
||||
fn utf8_env_map() -> BTreeMap<String, String> {
|
||||
env::vars_os()
|
||||
.filter_map(|(key, value)| Some((key.into_string().ok()?, value.into_string().ok()?)))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn default_ca_bundle_path() -> PathBuf {
|
||||
env::var_os("HOME")
|
||||
.map_or_else(|| PathBuf::from("."), PathBuf::from)
|
||||
|
||||
@@ -109,7 +109,11 @@ impl SandboxConfig {
|
||||
pub fn detect_container_environment() -> ContainerEnvironment {
|
||||
let proc_1_cgroup = fs::read_to_string("/proc/1/cgroup").ok();
|
||||
detect_container_environment_from(SandboxDetectionInputs {
|
||||
env_pairs: env::vars().collect(),
|
||||
// `env::vars()` panics on non-UTF-8 values (e.g. zsh exports a
|
||||
// metafied `$_` for non-ASCII paths); skip those entries instead.
|
||||
env_pairs: env::vars_os()
|
||||
.filter_map(|(key, value)| Some((key.into_string().ok()?, value.into_string().ok()?)))
|
||||
.collect(),
|
||||
dockerenv_exists: Path::new("/.dockerenv").exists(),
|
||||
containerenv_exists: Path::new("/run/.containerenv").exists(),
|
||||
proc_1_cgroup: proc_1_cgroup.as_deref(),
|
||||
|
||||
@@ -257,6 +257,34 @@ fn local_smoke_commands_do_not_require_live_credentials() {
|
||||
fs::remove_dir_all(temp_dir).expect("cleanup temp dir");
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn doctor_tolerates_non_utf8_environment_values() {
|
||||
use std::ffi::OsStr;
|
||||
use std::os::unix::ffi::OsStrExt;
|
||||
|
||||
// given: zsh exports a metafied (non-UTF-8) `$_` when the command path
|
||||
// contains non-ASCII characters such as `下載`
|
||||
let temp_dir = unique_temp_dir("non-utf8-env");
|
||||
let config_home = temp_dir.join(".claw");
|
||||
fs::create_dir_all(&config_home).expect("config home should exist");
|
||||
let metafied_path = OsStr::from_bytes(b"/home/user/\xe4\xb8\x83\xab\xe8\xbc\x83\xa9/claw");
|
||||
|
||||
// when
|
||||
let output = offline_command_in(&temp_dir, &config_home)
|
||||
.env("_", metafied_path)
|
||||
.arg("doctor")
|
||||
.output()
|
||||
.expect("claw should launch");
|
||||
|
||||
// then
|
||||
assert_success(&output);
|
||||
let stdout = String::from_utf8(output.stdout).expect("stdout should be utf8");
|
||||
assert!(stdout.contains("Doctor"));
|
||||
|
||||
fs::remove_dir_all(temp_dir).expect("cleanup temp dir");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn local_subcommand_help_does_not_fall_through_to_runtime_or_provider_calls() {
|
||||
let temp_dir = unique_temp_dir("subcommand-help");
|
||||
|
||||
Reference in new issue
Block a user