From 5fa80a16ec35254300877e49a08ed5b3fd86eecc Mon Sep 17 00:00:00 2001 From: Adam Perry Date: Tue, 16 Jun 2026 21:37:12 +0000 Subject: [PATCH] exec-server: test foreign cwd rejection before launch (#28129) --- codex-rs/exec-server/tests/exec_process.rs | 76 ++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/codex-rs/exec-server/tests/exec_process.rs b/codex-rs/exec-server/tests/exec_process.rs index 755e573ce3..840f5c8997 100644 --- a/codex-rs/exec-server/tests/exec_process.rs +++ b/codex-rs/exec-server/tests/exec_process.rs @@ -10,6 +10,7 @@ use codex_exec_server::ExecOutputStream; use codex_exec_server::ExecParams; use codex_exec_server::ExecProcess; use codex_exec_server::ExecProcessEvent; +use codex_exec_server::ExecServerError; use codex_exec_server::ProcessId; use codex_exec_server::ProcessSignal; use codex_exec_server::ReadResponse; @@ -777,6 +778,81 @@ async fn exec_process_uses_requested_cwd(use_remote: bool) -> Result<()> { Ok(()) } +#[test_case(false ; "local")] +#[test_case(true ; "remote")] +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +// Serialize tests that launch a real exec-server process through the full CLI. +#[serial_test::serial(remote_exec_server)] +async fn exec_process_rejects_non_native_cwd_without_reserving_process_id( + use_remote: bool, +) -> Result<()> { + let context = create_process_context(use_remote).await?; + let process_id = ProcessId::from("proc-non-native-cwd"); + let cwd = PathUri::parse(if cfg!(windows) { + "file:///usr/local/checkout" + } else { + "file://server/share/checkout" + })?; + let source = match cwd.to_abs_path() { + Ok(path) => anyhow::bail!( + "cwd should not be native on this host: {}", + path.as_path().display() + ), + Err(source) => source, + }; + let current_exe = std::env::current_exe()?; + let argv = vec![ + current_exe.to_string_lossy().into_owned(), + "--list".to_string(), + ]; + let error = match context + .backend + .start(ExecParams { + process_id: process_id.clone(), + argv: argv.clone(), + cwd: cwd.clone(), + env_policy: /*env_policy*/ None, + env: Default::default(), + tty: false, + pipe_stdin: false, + arg0: None, + }) + .await + { + Ok(_) => anyhow::bail!("non-native cwd should fail before process launch"), + Err(error) => error, + }; + let ExecServerError::Server { code, message } = error else { + anyhow::bail!("unexpected non-native cwd error: {error}"); + }; + assert_eq!( + (code, message), + ( + -32602, + format!("cwd URI `{cwd}` is not valid on this exec-server host: {source}") + ) + ); + + let session = context + .backend + .start(ExecParams { + process_id, + argv, + cwd: PathUri::from_path(std::env::current_dir()?)?, + env_policy: /*env_policy*/ None, + env: Default::default(), + tty: false, + pipe_stdin: false, + arg0: None, + }) + .await?; + let wake_rx = session.process.subscribe_wake(); + let (_, exit_code, closed) = + collect_process_output_from_reads(session.process, wake_rx).await?; + assert_eq!((exit_code, closed), (Some(0), true)); + Ok(()) +} + #[test_case(false ; "local")] #[test_case(true ; "remote")] #[cfg_attr(not(unix), ignore = "Unix-only exec-server process test")]