path-uri: clarify host-native path conversion (#29501)

## Why

Downstream refactors are producing confusing code with this
functionality having a very generic name. Encoding the specific
conversion approach in the method name makes it clearer.

## What

Rename `PathUri::from_path` to `PathUri::from_host_native_path` and
update its Rust call sites.
This commit is contained in:
Adam Perry @ OpenAI
2026-06-23 00:02:33 +00:00
committed by GitHub
parent c53b1dae09
commit 11fab432be
31 changed files with 250 additions and 198 deletions
+8 -4
View File
@@ -1151,8 +1151,10 @@ mod tests {
.start(crate::ExecParams {
process_id: ProcessId::from("default-env-proc"),
argv: vec!["true".to_string()],
cwd: PathUri::from_path(std::env::current_dir().expect("read current dir"))
.expect("cwd URI"),
cwd: PathUri::from_host_native_path(
std::env::current_dir().expect("read current dir"),
)
.expect("cwd URI"),
env_policy: None,
env: Default::default(),
tty: false,
@@ -1188,8 +1190,10 @@ mod tests {
.start(crate::ExecParams {
process_id: ProcessId::from("local-sandbox-proc"),
argv: vec!["true".to_string()],
cwd: PathUri::from_path(std::env::current_dir().expect("read current dir"))
.expect("cwd URI"),
cwd: PathUri::from_host_native_path(
std::env::current_dir().expect("read current dir"),
)
.expect("cwd URI"),
env_policy: None,
env: Default::default(),
tty: false,
+3 -2
View File
@@ -314,8 +314,9 @@ mod tests {
#[test]
fn helper_protocol_uses_path_uris() -> serde_json::Result<()> {
let local_path = PathUri::from_path(std::env::current_dir().expect("cwd").join("file"))
.expect("path URI");
let local_path =
PathUri::from_host_native_path(std::env::current_dir().expect("cwd").join("file"))
.expect("path URI");
let paths = [
local_path,
PathUri::parse("file://server/share/file").expect("path URI"),
+2 -1
View File
@@ -956,7 +956,8 @@ mod tests {
ExecParams {
process_id: ProcessId::from("env-test"),
argv: vec!["true".to_string()],
cwd: PathUri::from_path(std::env::current_dir().expect("cwd")).expect("cwd URI"),
cwd: PathUri::from_host_native_path(std::env::current_dir().expect("cwd"))
.expect("cwd URI"),
env_policy: None,
env,
tty: false,
+2 -2
View File
@@ -519,7 +519,7 @@ mod tests {
let legacy_cwd = std::env::current_dir().expect("current directory");
let native_sandbox = FileSystemSandboxContext::from_permission_profile_with_cwd(
PermissionProfile::default(),
PathUri::from_path(&legacy_cwd).expect("cwd URI"),
PathUri::from_host_native_path(&legacy_cwd).expect("cwd URI"),
);
let mut legacy_sandbox =
serde_json::to_value(&native_sandbox).expect("sandbox should serialize");
@@ -531,7 +531,7 @@ mod tests {
.expect("legacy absolute path should deserialize");
let expected_sandbox = native_sandbox;
let expected = FsReadFileParams {
path: PathUri::from_path(legacy_path).expect("path URI"),
path: PathUri::from_host_native_path(legacy_path).expect("path URI"),
sandbox: Some(expected_sandbox.clone()),
};
@@ -274,7 +274,7 @@ mod tests {
)
.expect("runtime paths");
let handler = FileSystemHandler::new(runtime_paths);
let sandbox_cwd = PathUri::from_path(temp_dir.path()).expect("tempdir URI");
let sandbox_cwd = PathUri::from_host_native_path(temp_dir.path()).expect("tempdir URI");
let sandbox_context = |sandbox_policy| {
FileSystemSandboxContext::from_legacy_sandbox_policy(
sandbox_policy,
@@ -292,7 +292,8 @@ mod tests {
},
),
] {
let path = PathUri::from_path(temp_dir.path().join(file_name)).expect("path URI");
let path =
PathUri::from_host_native_path(temp_dir.path().join(file_name)).expect("path URI");
handler
.write_file(FsWriteFileParams {
@@ -312,7 +313,7 @@ mod tests {
.expect("canonicalize file");
assert_eq!(
canonicalized.path,
PathUri::from_path(
PathUri::from_host_native_path(
std::fs::canonicalize(temp_dir.path().join(file_name)).expect("canonical path"),
)
.expect("canonical path URI"),
@@ -27,7 +27,8 @@ fn exec_params_with_argv(process_id: &str, argv: Vec<String>) -> ExecParams {
ExecParams {
process_id: ProcessId::from(process_id),
argv,
cwd: PathUri::from_path(std::env::current_dir().expect("cwd")).expect("cwd URI"),
cwd: PathUri::from_host_native_path(std::env::current_dir().expect("cwd"))
.expect("cwd URI"),
env_policy: None,
env: inherited_path_env(),
tty: false,
+2 -1
View File
@@ -432,7 +432,8 @@ mod tests {
ExecParams {
process_id,
argv: sleep_then_print_argv(),
cwd: PathUri::from_path(std::env::current_dir().expect("cwd")).expect("cwd URI"),
cwd: PathUri::from_host_native_path(std::env::current_dir().expect("cwd"))
.expect("cwd URI"),
env_policy: None,
env,
tty: false,
+12 -12
View File
@@ -75,7 +75,7 @@ async fn assert_exec_process_starts_and_exits(use_remote: bool) -> Result<()> {
.start(ExecParams {
process_id: ProcessId::from("proc-1"),
argv: vec!["true".to_string()],
cwd: PathUri::from_path(std::env::current_dir()?)?,
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
env_policy: /*env_policy*/ None,
env: Default::default(),
tty: false,
@@ -218,7 +218,7 @@ async fn assert_exec_process_streams_output(use_remote: bool) -> Result<()> {
"-c".to_string(),
"sleep 0.05; printf 'session output\\n'".to_string(),
],
cwd: PathUri::from_path(std::env::current_dir()?)?,
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
env_policy: /*env_policy*/ None,
env: Default::default(),
tty: false,
@@ -251,7 +251,7 @@ async fn assert_exec_process_pushes_events(use_remote: bool) -> Result<()> {
"-c".to_string(),
"printf 'event output\\n'; sleep 0.1; printf 'event err\\n' >&2; sleep 0.1; exit 7".to_string(),
],
cwd: PathUri::from_path(std::env::current_dir()?)?,
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
env_policy: /*env_policy*/ None,
env: Default::default(),
tty: false,
@@ -300,7 +300,7 @@ async fn assert_exec_process_replays_events_after_close(use_remote: bool) -> Res
"-c".to_string(),
"printf 'late one\\n'; printf 'late two\\n'".to_string(),
],
cwd: PathUri::from_path(std::env::current_dir()?)?,
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
env_policy: /*env_policy*/ None,
env: Default::default(),
tty: false,
@@ -350,7 +350,7 @@ async fn assert_exec_process_retains_output_after_exit_until_streams_close(
DELAYED_OUTPUT_AFTER_EXIT_PARENT_ARG.to_string(),
release_path.to_string_lossy().into_owned(),
],
cwd: PathUri::from_path(std::env::current_dir()?)?,
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
env_policy: /*env_policy*/ None,
env: Default::default(),
tty: false,
@@ -425,7 +425,7 @@ async fn assert_exec_process_write_then_read(use_remote: bool) -> Result<()> {
"-c".to_string(),
"IFS= read line; printf 'from-stdin:%s\\n' \"$line\"".to_string(),
],
cwd: PathUri::from_path(std::env::current_dir()?)?,
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
env_policy: /*env_policy*/ None,
env: Default::default(),
tty: true,
@@ -464,7 +464,7 @@ async fn assert_exec_process_write_then_read_without_tty(use_remote: bool) -> Re
"-c".to_string(),
"IFS= read line; printf 'from-stdin:%s\\n' \"$line\"".to_string(),
],
cwd: PathUri::from_path(std::env::current_dir()?)?,
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
env_policy: /*env_policy*/ None,
env: Default::default(),
tty: false,
@@ -499,7 +499,7 @@ async fn assert_exec_process_rejects_write_without_pipe_stdin(use_remote: bool)
"-c".to_string(),
"sleep 0.3; if IFS= read -r line; then printf 'read:%s\\n' \"$line\"; else printf 'eof\\n'; fi".to_string(),
],
cwd: PathUri::from_path(std::env::current_dir()?)?,
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
env_policy: /*env_policy*/ None,
env: Default::default(),
tty: false,
@@ -535,7 +535,7 @@ async fn assert_exec_process_signal_interrupts_process(use_remote: bool) -> Resu
"-c".to_string(),
"trap 'printf \"signal:2\\n\"; exit 7' INT; printf 'ready\\n'; while :; do :; done".to_string(),
],
cwd: PathUri::from_path(std::env::current_dir()?)?,
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
env_policy: /*env_policy*/ None,
env: Default::default(),
tty: false,
@@ -590,7 +590,7 @@ async fn assert_exec_process_signal_reports_unsupported_on_windows(use_remote: b
"/C".to_string(),
"echo ready && ping -n 30 127.0.0.1 >NUL".to_string(),
],
cwd: PathUri::from_path(std::env::current_dir()?)?,
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
env_policy: /*env_policy*/ None,
env: Default::default(),
tty: false,
@@ -632,7 +632,7 @@ async fn assert_exec_process_preserves_queued_events_before_subscribe(
"-c".to_string(),
"printf 'queued output\\n'".to_string(),
],
cwd: PathUri::from_path(std::env::current_dir()?)?,
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
env_policy: /*env_policy*/ None,
env: Default::default(),
tty: false,
@@ -683,7 +683,7 @@ async fn remote_exec_process_recovers_after_transport_disconnect() -> Result<()>
)
.to_string(),
],
cwd: PathUri::from_path(std::env::current_dir()?)?,
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
env_policy: /*env_policy*/ None,
env: HashMap::from([
(
+16 -10
View File
@@ -45,7 +45,10 @@ async fn stream_stops_after_an_exact_block_boundary() -> Result<()> {
std::fs::write(&path, vec![b'x'; BLOCK_SIZE * 2])?;
let chunks = file_system
.read_file_stream(&PathUri::from_path(path)?, /*sandbox*/ None)
.read_file_stream(
&PathUri::from_host_native_path(path)?,
/*sandbox*/ None,
)
.await?
.try_collect::<Vec<_>>()
.await?;
@@ -64,7 +67,7 @@ async fn completed_streams_release_handle_capacity() -> Result<()> {
let tmp = TempDir::new()?;
let path = tmp.path().join("repeated.txt");
std::fs::write(&path, b"repeated")?;
let path = PathUri::from_path(path)?;
let path = PathUri::from_host_native_path(path)?;
for _ in 0..=OPEN_FILE_LIMIT {
let chunks = file_system
@@ -88,7 +91,7 @@ async fn stream_rejects_platform_sandbox() -> Result<()> {
let result = file_system
.read_file_stream(
&PathUri::from_path(&path)?,
&PathUri::from_host_native_path(&path)?,
Some(&read_only_sandbox(tmp.path().to_path_buf())),
)
.await;
@@ -120,7 +123,7 @@ async fn file_reads_reject_fifo_without_waiting_for_a_writer() -> Result<()> {
);
}
let path_uri = PathUri::from_path(&path)?;
let path_uri = PathUri::from_host_native_path(&path)?;
let read_error = timeout(
Duration::from_secs(1),
file_system.read_file(&path_uri, /*sandbox*/ None),
@@ -158,7 +161,7 @@ async fn file_reads_reject_named_pipes() -> Result<()> {
let read_error = timeout(
Duration::from_secs(1),
file_system.read_file(
&PathUri::from_path(std::path::Path::new(&read_path))?,
&PathUri::from_host_native_path(std::path::Path::new(&read_path))?,
/*sandbox*/ None,
),
)
@@ -173,7 +176,7 @@ async fn file_reads_reject_named_pipes() -> Result<()> {
let stream_result = timeout(
Duration::from_secs(1),
file_system.read_file_stream(
&PathUri::from_path(std::path::Path::new(&stream_path))?,
&PathUri::from_host_native_path(std::path::Path::new(&stream_path))?,
/*sandbox*/ None,
),
)
@@ -202,7 +205,10 @@ async fn stream_keeps_reading_the_open_file_after_path_replacement() -> Result<(
let path = tmp.path().join("replaceable.bin");
std::fs::write(&path, vec![b'a'; BLOCK_SIZE + 1])?;
let mut stream = file_system
.read_file_stream(&PathUri::from_path(&path)?, /*sandbox*/ None)
.read_file_stream(
&PathUri::from_host_native_path(&path)?,
/*sandbox*/ None,
)
.await?;
assert_eq!(
@@ -236,7 +242,7 @@ async fn read_block_supports_non_sequential_offsets_and_lengths() -> Result<()>
let open = client
.fs_open(FsOpenParams {
handle_id: Uuid::new_v4().simple().to_string(),
path: PathUri::from_path(path)?,
path: PathUri::from_host_native_path(path)?,
sandbox: None,
})
.await?;
@@ -295,7 +301,7 @@ async fn open_enforces_the_per_connection_limit_and_close_releases_capacity() ->
let tmp = TempDir::new()?;
let path = tmp.path().join("limited.bin");
std::fs::write(&path, b"limited")?;
let path = PathUri::from_path(path)?;
let path = PathUri::from_host_native_path(path)?;
let mut handles = Vec::with_capacity(OPEN_FILE_LIMIT);
for _ in 0..OPEN_FILE_LIMIT {
let open = client
@@ -359,7 +365,7 @@ async fn open_rejects_handle_ids_longer_than_32_bytes() -> Result<()> {
let error = client
.fs_open(FsOpenParams {
handle_id: "x".repeat(33),
path: PathUri::from_path(path)?,
path: PathUri::from_host_native_path(path)?,
sandbox: None,
})
.await
@@ -66,7 +66,10 @@ async fn file_system_get_metadata_reports_files_and_directories(
std::fs::create_dir(&directory_path)?;
let file_metadata = file_system
.get_metadata(&PathUri::from_path(&file_path)?, /*sandbox*/ None)
.get_metadata(
&PathUri::from_host_native_path(&file_path)?,
/*sandbox*/ None,
)
.await
.with_context(|| format!("mode={implementation}"))?;
assert_eq!(
@@ -83,7 +86,10 @@ async fn file_system_get_metadata_reports_files_and_directories(
assert!(file_metadata.modified_at_ms > 0);
let directory_metadata = file_system
.get_metadata(&PathUri::from_path(&directory_path)?, /*sandbox*/ None)
.get_metadata(
&PathUri::from_host_native_path(&directory_path)?,
/*sandbox*/ None,
)
.await
.with_context(|| format!("mode={implementation}"))?;
assert_eq!(
@@ -116,7 +122,7 @@ async fn file_system_create_directory_creates_nested_directories(
file_system
.create_directory(
&PathUri::from_path(&nested_dir)?,
&PathUri::from_host_native_path(&nested_dir)?,
CreateDirectoryOptions { recursive: true },
/*sandbox*/ None,
)
@@ -140,7 +146,7 @@ async fn file_system_write_file_writes_bytes(
let file_path = tmp.path().join("note.txt");
file_system
.write_file(
&PathUri::from_path(&file_path)?,
&PathUri::from_host_native_path(&file_path)?,
b"hello from trait".to_vec(),
/*sandbox*/ None,
)
@@ -155,21 +161,21 @@ async fn file_system_write_file_writes_bytes(
fn path_uri_join_and_parent_preserve_lexical_paths() -> Result<()> {
let tmp = TempDir::new()?;
let source_dir = tmp.path().join("source");
let source_dir_uri = PathUri::from_path(&source_dir)?;
let source_dir_uri = PathUri::from_host_native_path(&source_dir)?;
let joined_nested = source_dir_uri.join("nested/note.txt")?;
assert_eq!(
joined_nested,
PathUri::from_path(source_dir.join("nested").join("note.txt"))?
PathUri::from_host_native_path(source_dir.join("nested").join("note.txt"))?
);
let joined_parent = joined_nested.parent();
assert_eq!(
joined_parent,
Some(PathUri::from_path(source_dir.join("nested"))?)
Some(PathUri::from_host_native_path(source_dir.join("nested"))?)
);
let joined_parent_traversal = source_dir_uri.join("../outside")?;
assert_eq!(
joined_parent_traversal,
PathUri::from_path(source_dir.join("../outside"))?
PathUri::from_host_native_path(source_dir.join("../outside"))?
);
Ok(())
}
@@ -188,7 +194,10 @@ async fn file_system_read_file_returns_bytes(
std::fs::write(&file_path, "hello from trait")?;
let contents = file_system
.read_file(&PathUri::from_path(&file_path)?, /*sandbox*/ None)
.read_file(
&PathUri::from_host_native_path(&file_path)?,
/*sandbox*/ None,
)
.await
.with_context(|| format!("mode={implementation}"))?;
assert_eq!(contents, b"hello from trait");
@@ -213,7 +222,10 @@ async fn file_system_read_file_stream_returns_bounded_chunks(
std::fs::write(&file_path, &contents)?;
let chunks = file_system
.read_file_stream(&PathUri::from_path(file_path)?, /*sandbox*/ None)
.read_file_stream(
&PathUri::from_host_native_path(file_path)?,
/*sandbox*/ None,
)
.await
.with_context(|| format!("mode={implementation}"))?
.try_collect::<Vec<_>>()
@@ -249,7 +261,10 @@ async fn file_system_read_file_text_returns_string(
std::fs::write(&file_path, "hello from trait")?;
let contents = file_system
.read_file_text(&PathUri::from_path(&file_path)?, /*sandbox*/ None)
.read_file_text(
&PathUri::from_host_native_path(&file_path)?,
/*sandbox*/ None,
)
.await
.with_context(|| format!("mode={implementation}"))?;
assert_eq!(contents, "hello from trait");
@@ -271,8 +286,8 @@ async fn file_system_copy_copies_file(implementation: FileSystemImplementation)
file_system
.copy(
&PathUri::from_path(&source_file)?,
&PathUri::from_path(&copied_file)?,
&PathUri::from_host_native_path(&source_file)?,
&PathUri::from_host_native_path(&copied_file)?,
CopyOptions { recursive: false },
/*sandbox*/ None,
)
@@ -302,8 +317,8 @@ async fn file_system_copy_copies_directory_recursively(
file_system
.copy(
&PathUri::from_path(&source_dir)?,
&PathUri::from_path(&copied_dir)?,
&PathUri::from_host_native_path(&source_dir)?,
&PathUri::from_host_native_path(&copied_dir)?,
CopyOptions { recursive: true },
/*sandbox*/ None,
)
@@ -332,7 +347,10 @@ async fn file_system_read_directory_lists_entries(
std::fs::write(source_dir.join("root.txt"), "hello")?;
let mut entries = file_system
.read_directory(&PathUri::from_path(&source_dir)?, /*sandbox*/ None)
.read_directory(
&PathUri::from_host_native_path(&source_dir)?,
/*sandbox*/ None,
)
.await
.with_context(|| format!("mode={implementation}"))?;
entries.sort_by(|left, right| left.file_name.cmp(&right.file_name));
@@ -370,7 +388,7 @@ async fn file_system_remove_removes_directory(
file_system
.remove(
&PathUri::from_path(&directory_path)?,
&PathUri::from_host_native_path(&directory_path)?,
RemoveOptions {
recursive: true,
force: true,
@@ -398,7 +416,7 @@ async fn file_system_write_file_reports_missing_parent(
let error = match file_system
.write_file(
&PathUri::from_path(&missing_parent_path)?,
&PathUri::from_host_native_path(&missing_parent_path)?,
b"hello from trait".to_vec(),
/*sandbox*/ None,
)
@@ -432,8 +450,8 @@ async fn file_system_copy_rejects_directory_without_recursive(
let error = file_system
.copy(
&PathUri::from_path(&source_dir)?,
&PathUri::from_path(tmp.path().join("dest"))?,
&PathUri::from_host_native_path(&source_dir)?,
&PathUri::from_host_native_path(tmp.path().join("dest"))?,
CopyOptions { recursive: false },
/*sandbox*/ None,
)
@@ -465,7 +483,7 @@ async fn file_system_sandboxed_metadata_and_read_allow_readable_root(
let sandbox = read_only_sandbox(allowed_dir);
let metadata = file_system
.get_metadata(&PathUri::from_path(&file_path)?, Some(&sandbox))
.get_metadata(&PathUri::from_host_native_path(&file_path)?, Some(&sandbox))
.await
.with_context(|| format!("mode={implementation}"))?;
assert_eq!(
@@ -481,7 +499,7 @@ async fn file_system_sandboxed_metadata_and_read_allow_readable_root(
);
let contents = file_system
.read_file(&PathUri::from_path(&file_path)?, Some(&sandbox))
.read_file(&PathUri::from_host_native_path(&file_path)?, Some(&sandbox))
.await
.with_context(|| format!("mode={implementation}"))?;
assert_eq!(contents, b"sandboxed hello");
@@ -505,8 +523,8 @@ pub(crate) async fn assert_canonicalize_resolves_directory_alias(
std::fs::write(&file_path, "canonical hello")?;
create_directory_alias(&source_dir, &alias_dir)?;
let requested_path = PathUri::from_path(alias_dir.join("nested").join("note.txt"))?;
let expected_path = PathUri::from_path(std::fs::canonicalize(&file_path)?)?;
let requested_path = PathUri::from_host_native_path(alias_dir.join("nested").join("note.txt"))?;
let expected_path = PathUri::from_host_native_path(std::fs::canonicalize(&file_path)?)?;
assert_ne!(requested_path, expected_path);
let canonical_path = file_system
@@ -535,8 +553,8 @@ pub(crate) async fn assert_sandboxed_canonicalize_resolves_directory_alias(
create_directory_alias(&source_dir, &alias_dir)?;
let sandbox = read_only_sandbox(tmp.path().to_path_buf());
let requested_path = PathUri::from_path(alias_dir.join("nested").join("note.txt"))?;
let expected_path = PathUri::from_path(std::fs::canonicalize(&file_path)?)?;
let requested_path = PathUri::from_host_native_path(alias_dir.join("nested").join("note.txt"))?;
let expected_path = PathUri::from_host_native_path(std::fs::canonicalize(&file_path)?)?;
assert_ne!(requested_path, expected_path);
let canonical_path = file_system
@@ -591,7 +609,7 @@ async fn file_system_sandboxed_write_allows_additional_write_root(
file_system
.write_file(
&PathUri::from_path(&file_path)?,
&PathUri::from_host_native_path(&file_path)?,
b"created".to_vec(),
Some(&sandbox),
)
@@ -617,8 +635,8 @@ async fn file_system_copy_rejects_copying_directory_into_descendant(
let error = file_system
.copy(
&PathUri::from_path(&source_dir)?,
&PathUri::from_path(source_dir.join("nested").join("copy"))?,
&PathUri::from_host_native_path(&source_dir)?,
&PathUri::from_host_native_path(source_dir.join("nested").join("copy"))?,
CopyOptions { recursive: true },
/*sandbox*/ None,
)
+34 -25
View File
@@ -187,7 +187,7 @@ async fn sandboxed_file_system_helper_finds_bwrap_on_preserved_path() -> Result<
file_system
.write_file(
&PathUri::from_path(&file_path)?,
&PathUri::from_host_native_path(&file_path)?,
b"written through fs helper".to_vec(),
Some(&sandbox),
)
@@ -221,7 +221,10 @@ async fn file_system_get_metadata_reports_symlink_targets(
let symlink_path = tmp.path().join("note-link.txt");
symlink(&file_path, &symlink_path)?;
let symlink_metadata = file_system
.get_metadata(&PathUri::from_path(&symlink_path)?, /*sandbox*/ None)
.get_metadata(
&PathUri::from_host_native_path(&symlink_path)?,
/*sandbox*/ None,
)
.await
.with_context(|| format!("mode={implementation}"))?;
assert_eq!(
@@ -243,7 +246,7 @@ async fn file_system_get_metadata_reports_symlink_targets(
symlink(&dir_path, &dir_symlink_path)?;
let dir_symlink_metadata = file_system
.get_metadata(
&PathUri::from_path(&dir_symlink_path)?,
&PathUri::from_host_native_path(&dir_symlink_path)?,
/*sandbox*/ None,
)
.await
@@ -278,7 +281,7 @@ async fn file_system_sandboxed_write_rejects_unwritable_path(
let sandbox = read_only_sandbox(tmp.path().to_path_buf());
let error = match file_system
.write_file(
&PathUri::from_path(&blocked_path)?,
&PathUri::from_host_native_path(&blocked_path)?,
b"nope".to_vec(),
Some(&sandbox),
)
@@ -314,7 +317,7 @@ async fn file_system_sandboxed_write_allows_explicit_alias_roots(
file_system
.write_file(
&PathUri::from_path(&file_path)?,
&PathUri::from_host_native_path(&file_path)?,
b"created".to_vec(),
Some(&sandbox),
)
@@ -345,7 +348,10 @@ async fn file_system_sandboxed_read_rejects_symlink_escape(
let requested_path = allowed_dir.join("link").join("secret.txt");
let sandbox = read_only_sandbox(allowed_dir);
let error = match file_system
.read_file(&PathUri::from_path(&requested_path)?, Some(&sandbox))
.read_file(
&PathUri::from_host_native_path(&requested_path)?,
Some(&sandbox),
)
.await
{
Ok(_) => anyhow::bail!("read should be blocked"),
@@ -375,7 +381,7 @@ async fn file_system_sandboxed_read_rejects_symlink_parent_dotdot_escape(
symlink(&outside_dir, allowed_dir.join("link"))?;
let requested_path =
PathUri::from_path(allowed_dir.join("link").join("..").join("secret.txt"))?;
PathUri::from_host_native_path(allowed_dir.join("link").join("..").join("secret.txt"))?;
let sandbox = read_only_sandbox(allowed_dir);
let error = match file_system.read_file(&requested_path, Some(&sandbox)).await {
Ok(_) => anyhow::bail!("read should fail after path normalization"),
@@ -411,7 +417,7 @@ async fn file_system_sandboxed_write_rejects_symlink_escape(
let sandbox = workspace_write_sandbox(allowed_dir);
let error = match file_system
.write_file(
&PathUri::from_path(&requested_path)?,
&PathUri::from_host_native_path(&requested_path)?,
b"nope".to_vec(),
Some(&sandbox),
)
@@ -449,7 +455,7 @@ async fn file_system_sandboxed_write_preserves_existing_hard_link(
let sandbox = workspace_write_sandbox(allowed_dir);
file_system
.write_file(
&PathUri::from_path(&hard_link)?,
&PathUri::from_host_native_path(&hard_link)?,
b"updated through existing hard link\n".to_vec(),
Some(&sandbox),
)
@@ -495,7 +501,7 @@ async fn file_system_create_directory_rejects_symlink_escape(
let sandbox = workspace_write_sandbox(allowed_dir);
let error = match file_system
.create_directory(
&PathUri::from_path(&requested_path)?,
&PathUri::from_host_native_path(&requested_path)?,
CreateDirectoryOptions { recursive: false },
Some(&sandbox),
)
@@ -530,7 +536,10 @@ async fn file_system_read_directory_rejects_symlink_escape(
let requested_path = allowed_dir.join("link");
let sandbox = read_only_sandbox(allowed_dir);
let error = match file_system
.read_directory(&PathUri::from_path(&requested_path)?, Some(&sandbox))
.read_directory(
&PathUri::from_host_native_path(&requested_path)?,
Some(&sandbox),
)
.await
{
Ok(_) => anyhow::bail!("read_directory should be blocked"),
@@ -562,8 +571,8 @@ async fn file_system_copy_rejects_symlink_escape_destination(
let sandbox = workspace_write_sandbox(allowed_dir.clone());
let error = match file_system
.copy(
&PathUri::from_path(allowed_dir.join("source.txt"))?,
&PathUri::from_path(&requested_destination)?,
&PathUri::from_host_native_path(allowed_dir.join("source.txt"))?,
&PathUri::from_host_native_path(&requested_destination)?,
CopyOptions { recursive: false },
Some(&sandbox),
)
@@ -600,7 +609,7 @@ async fn file_system_remove_removes_symlink_not_target(
let sandbox = workspace_write_sandbox(allowed_dir);
file_system
.remove(
&PathUri::from_path(&symlink_path)?,
&PathUri::from_host_native_path(&symlink_path)?,
RemoveOptions {
recursive: false,
force: false,
@@ -640,8 +649,8 @@ async fn file_system_copy_preserves_symlink_source(
let sandbox = workspace_write_sandbox(allowed_dir.clone());
file_system
.copy(
&PathUri::from_path(&source_symlink)?,
&PathUri::from_path(&copied_symlink)?,
&PathUri::from_host_native_path(&source_symlink)?,
&PathUri::from_host_native_path(&copied_symlink)?,
CopyOptions { recursive: false },
Some(&sandbox),
)
@@ -677,7 +686,7 @@ async fn file_system_remove_rejects_symlink_escape(
let sandbox = workspace_write_sandbox(allowed_dir);
let error = match file_system
.remove(
&PathUri::from_path(&requested_path)?,
&PathUri::from_host_native_path(&requested_path)?,
RemoveOptions {
recursive: false,
force: false,
@@ -718,8 +727,8 @@ async fn file_system_copy_rejects_symlink_escape_source(
let sandbox = workspace_write_sandbox(allowed_dir);
let error = match file_system
.copy(
&PathUri::from_path(&requested_source)?,
&PathUri::from_path(&requested_destination)?,
&PathUri::from_host_native_path(&requested_source)?,
&PathUri::from_host_native_path(&requested_destination)?,
CopyOptions { recursive: false },
Some(&sandbox),
)
@@ -752,8 +761,8 @@ async fn file_system_copy_preserves_symlinks_in_recursive_copy(
file_system
.copy(
&PathUri::from_path(&source_dir)?,
&PathUri::from_path(&copied_dir)?,
&PathUri::from_host_native_path(&source_dir)?,
&PathUri::from_host_native_path(&copied_dir)?,
CopyOptions { recursive: true },
/*sandbox*/ None,
)
@@ -798,8 +807,8 @@ async fn file_system_copy_ignores_unknown_special_files_in_recursive_copy(
file_system
.copy(
&PathUri::from_path(&source_dir)?,
&PathUri::from_path(&copied_dir)?,
&PathUri::from_host_native_path(&source_dir)?,
&PathUri::from_host_native_path(&copied_dir)?,
CopyOptions { recursive: true },
/*sandbox*/ None,
)
@@ -837,8 +846,8 @@ async fn file_system_copy_rejects_standalone_fifo_source(
let error = file_system
.copy(
&PathUri::from_path(&fifo_path)?,
&PathUri::from_path(tmp.path().join("copied"))?,
&PathUri::from_host_native_path(&fifo_path)?,
&PathUri::from_host_native_path(tmp.path().join("copied"))?,
CopyOptions { recursive: false },
/*sandbox*/ None,
)
@@ -74,7 +74,10 @@ async fn file_system_remote_fs_helper_respects_windows_sandbox_write_policy() ->
let readable_file = readonly_dir.join("readable.txt");
std::fs::write(&readable_file, b"readable")?;
let read_result = file_system
.read_file(&PathUri::from_path(&readable_file)?, Some(&sandbox))
.read_file(
&PathUri::from_host_native_path(&readable_file)?,
Some(&sandbox),
)
.await;
// Some local Windows hosts cannot create restricted tokens. Reaching that
// error still proves the remote fs helper went through the Windows sandbox
@@ -87,7 +90,7 @@ async fn file_system_remote_fs_helper_respects_windows_sandbox_write_policy() ->
let blocked_file = readonly_dir.join("blocked.txt");
let error = file_system
.write_file(
&PathUri::from_path(&blocked_file)?,
&PathUri::from_host_native_path(&blocked_file)?,
b"blocked".to_vec(),
Some(&sandbox),
)
@@ -104,7 +107,7 @@ async fn file_system_remote_fs_helper_respects_windows_sandbox_write_policy() ->
fn read_only_sandbox_for_cwd(cwd: std::path::PathBuf) -> Result<FileSystemSandboxContext> {
Ok(FileSystemSandboxContext::from_legacy_sandbox_policy(
SandboxPolicy::new_read_only_policy(),
PathUri::from_path(cwd)?,
PathUri::from_host_native_path(cwd)?,
)?)
}
+2 -2
View File
@@ -144,7 +144,7 @@ async fn remote_environment_routes_encrypted_exec_server_rpc() -> Result<()> {
.exec(ExecParams {
process_id: ProcessId::from("proc-1"),
argv: vec!["true".to_string()],
cwd: PathUri::from_path(std::env::current_dir()?)?,
cwd: PathUri::from_host_native_path(std::env::current_dir()?)?,
env_policy: None,
env: HashMap::new(),
tty: false,
@@ -167,7 +167,7 @@ async fn remote_environment_routes_encrypted_exec_server_rpc() -> Result<()> {
std::fs::write(&large_file_path, &large_file_contents)?;
let read_response = client
.fs_read_file(FsReadFileParams {
path: PathUri::from_path(large_file_path)?,
path: PathUri::from_host_native_path(large_file_path)?,
sandbox: None,
})
.await?;