Compare commits

..

1 Commits

Author SHA1 Message Date
David Wiesen
252706cec1 Skip WindowsApps helper read roots 2026-04-19 12:03:36 -07:00
3 changed files with 38 additions and 41 deletions

View File

@@ -7,40 +7,6 @@ use std::collections::HashSet;
pub const CODEX_THREAD_ID_ENV_VAR: &str = "CODEX_THREAD_ID";
#[cfg(windows)]
const CORE_VARS: &[&str] = &[
// Core path resolution
"PATH",
"PATHEXT",
// Shell and system roots
"COMSPEC",
"SYSTEMROOT",
"SYSTEMDRIVE",
// User context and profiles
"HOME",
"USERNAME",
"USERDOMAIN",
"USERPROFILE",
"HOMEDRIVE",
"HOMEPATH",
// Program locations
"PROGRAMFILES",
"PROGRAMFILES(X86)",
"PROGRAMW6432",
"PROGRAMDATA",
// App data and caches
"LOCALAPPDATA",
"APPDATA",
// Temp locations
"TEMP",
"TMP",
];
#[cfg(not(windows))]
const CORE_VARS: &[&str] = &[
"HOME", "LOGNAME", "PATH", "SHELL", "USER", "USERNAME", "TMPDIR", "TEMP", "TMP",
];
/// Construct an environment map based on the rules in the specified policy. The
/// resulting map can be passed directly to `Command::envs()` after calling
/// `env_clear()` to ensure no unintended variables are leaked to the spawned
@@ -72,6 +38,9 @@ where
ShellEnvironmentPolicyInherit::All => vars.into_iter().collect(),
ShellEnvironmentPolicyInherit::None => HashMap::new(),
ShellEnvironmentPolicyInherit::Core => {
const CORE_VARS: &[&str] = &[
"HOME", "LOGNAME", "PATH", "SHELL", "USER", "USERNAME", "TMPDIR", "TEMP", "TMP",
];
let allow: HashSet<&str> = CORE_VARS.iter().copied().collect();
let is_core_var = |name: &str| {
if cfg!(target_os = "windows") {

View File

@@ -172,9 +172,6 @@ fn test_core_inherit_respects_case_insensitive_names_on_windows() {
let vars = make_vars(&[
("Path", "C:\\Windows\\System32"),
("TEMP", "C:\\Temp"),
("SystemRoot", "C:\\Windows"),
("APPDATA", "C:\\Users\\codex\\AppData\\Roaming"),
("ProgramFiles", "C:\\Program Files"),
("FOO", "bar"),
]);
@@ -189,9 +186,6 @@ fn test_core_inherit_respects_case_insensitive_names_on_windows() {
let mut expected: HashMap<String, String> = hashmap! {
"Path".to_string() => "C:\\Windows\\System32".to_string(),
"TEMP".to_string() => "C:\\Temp".to_string(),
"SystemRoot".to_string() => "C:\\Windows".to_string(),
"APPDATA".to_string() => "C:\\Users\\codex\\AppData\\Roaming".to_string(),
"ProgramFiles".to_string() => "C:\\Program Files".to_string(),
};
expected.insert(CODEX_THREAD_ID_ENV_VAR.to_string(), thread_id.to_string());

View File

@@ -58,6 +58,7 @@ const WINDOWS_PLATFORM_DEFAULT_READ_ROOTS: &[&str] = &[
r"C:\Program Files (x86)",
r"C:\ProgramData",
];
const WINDOWS_APPS_ROOT: &str = r"C:\Program Files\WindowsApps";
pub fn sandbox_dir(codex_home: &Path) -> PathBuf {
codex_home.join(".sandbox")
@@ -334,8 +335,9 @@ fn gather_helper_read_roots(codex_home: &Path) -> Vec<PathBuf> {
let mut roots = Vec::new();
if let Ok(exe) = std::env::current_exe()
&& let Some(dir) = exe.parent()
&& let Some(read_root) = helper_exe_dir_read_root(dir)
{
roots.push(dir.to_path_buf());
roots.push(read_root);
}
let helper_dir = helper_bin_dir(codex_home);
let _ = std::fs::create_dir_all(&helper_dir);
@@ -343,6 +345,19 @@ fn gather_helper_read_roots(codex_home: &Path) -> Vec<PathBuf> {
roots
}
fn helper_exe_dir_read_root(dir: &Path) -> Option<PathBuf> {
if is_windows_apps_dir(dir) {
return None;
}
Some(dir.to_path_buf())
}
fn is_windows_apps_dir(path: &Path) -> bool {
let path_key = canonical_path_key(path);
let windows_apps_key = canonical_path_key(Path::new(WINDOWS_APPS_ROOT));
path_key == windows_apps_key || path_key.starts_with(&format!("{windows_apps_key}/"))
}
fn gather_legacy_full_read_roots(
command_cwd: &Path,
policy: &SandboxPolicy,
@@ -804,6 +819,8 @@ mod tests {
use super::WINDOWS_PLATFORM_DEFAULT_READ_ROOTS;
use super::gather_legacy_full_read_roots;
use super::gather_read_roots;
use super::helper_exe_dir_read_root;
use super::is_windows_apps_dir;
use super::loopback_proxy_port_from_url;
use super::offline_proxy_settings_from_env;
use super::profile_read_roots;
@@ -1009,6 +1026,23 @@ mod tests {
assert!(roots.contains(&expected));
}
#[test]
fn helper_exe_dir_read_root_skips_windows_apps_dir() {
let windows_apps_dir =
PathBuf::from(r"C:\Program Files\WindowsApps\OpenAI.Codex_1.2.3.4_x64__test\app");
assert!(is_windows_apps_dir(&windows_apps_dir));
assert_eq!(helper_exe_dir_read_root(&windows_apps_dir), None);
}
#[test]
fn helper_exe_dir_read_root_keeps_normal_install_dir() {
let normal_dir = PathBuf::from(r"C:\Program Files\OpenAI\Codex\app");
assert!(!is_windows_apps_dir(&normal_dir));
assert_eq!(helper_exe_dir_read_root(&normal_dir), Some(normal_dir));
}
#[test]
fn restricted_read_roots_skip_platform_defaults_when_disabled() {
let tmp = TempDir::new().expect("tempdir");