[codex] make PathUri::from_abs_path infallible (#27976)

## Why

`PathUri::from_abs_path` can fail for absolute paths that do not have a
normal `file:` URI representation, forcing filesystem call sites to
handle a conversion error even though the original path can be preserved
losslessly.

## What

Make `from_abs_path` infallible and migrate its callers. Unrepresentable
paths use `file:///%00/bad/path/<base64>`, encoding Unix bytes or
Windows UTF-16LE; `to_abs_path` validates and decodes that fallback. The
leading encoded null reserves a namespace that cannot collide with a
real Unix or Windows path, and fallback URIs remain opaque to lexical
path operations.

## Validation

Added path-URI coverage for Unix null and non-UTF-8 paths, Windows
device/verbatim and non-Unicode paths, serialization, malformed
fallbacks, opaque lexical operations, invalid native payloads, and
literal `/bad/path` collision resistance.
This commit is contained in:
Adam Perry @ OpenAI
2026-06-12 16:58:42 -07:00
committed by GitHub
parent eb46984aaa
commit 968a3ac9c1
42 changed files with 356 additions and 323 deletions
+1 -1
View File
@@ -882,7 +882,7 @@ mod tests {
std::env::current_exe().expect("current exe").as_path(),
)
.expect("absolute current exe");
let path = codex_utils_path_uri::PathUri::from_abs_path(&path).expect("path URI");
let path = codex_utils_path_uri::PathUri::from_abs_path(&path);
let sandbox = crate::FileSystemSandboxContext::from_permission_profile(
codex_protocol::models::PermissionProfile::from_runtime_permissions(
&codex_protocol::permissions::FileSystemSandboxPolicy::restricted(Vec::new()),
+3 -7
View File
@@ -145,11 +145,7 @@ fn sandbox_cwd(sandbox: &FileSystemSandboxContext) -> Result<SandboxCwd, JSONRPC
let native = AbsolutePathBuf::from_absolute_path(current_sandbox_cwd().map_err(io_error)?)
.map_err(|err| invalid_request(format!("current directory is not absolute: {err}")))?;
let uri = PathUri::from_abs_path(&native).map_err(|err| {
invalid_request(format!(
"current directory cannot be represented as a file URI: {err}"
))
})?;
let uri = PathUri::from_abs_path(&native);
Ok(SandboxCwd { uri, native })
}
@@ -519,7 +515,7 @@ mod tests {
.expect("runtime paths");
let runner = FileSystemSandboxRunner::new(runtime_paths);
let native_cwd = AbsolutePathBuf::current_dir().expect("cwd");
let cwd = PathUri::from_abs_path(&native_cwd).expect("cwd URI");
let cwd = PathUri::from_abs_path(&native_cwd);
let file_system_policy =
restricted_policy(vec![path_entry(native_cwd, FileSystemAccessMode::Write)]);
let network_policy = NetworkSandboxPolicy::Restricted;
@@ -538,7 +534,7 @@ mod tests {
fn sandbox_cwd_uses_context_cwd() {
let native_cwd = AbsolutePathBuf::from_absolute_path(std::env::temp_dir().as_path())
.expect("absolute cwd");
let cwd = PathUri::from_abs_path(&native_cwd).expect("cwd URI");
let cwd = PathUri::from_abs_path(&native_cwd);
let policy = restricted_policy(vec![special_entry(
FileSystemSpecialPath::project_roots(/*subpath*/ None),
FileSystemAccessMode::Write,
@@ -423,7 +423,7 @@ impl DirectFileSystem {
let path = path.to_abs_path()?;
let canonicalized =
AbsolutePathBuf::from_absolute_path(tokio::fs::canonicalize(path.as_path()).await?)?;
PathUri::from_abs_path(&canonicalized)
Ok(PathUri::from_abs_path(&canonicalized))
}
async fn read_file(
@@ -404,6 +404,6 @@ mod tests {
}
fn path_uri(name: &str) -> PathUri {
PathUri::from_abs_path(&absolute_test_path(name)).expect("path URI")
PathUri::from_abs_path(&absolute_test_path(name))
}
}