mirror of
https://github.com/openai/codex.git
synced 2026-04-23 22:24:57 +00:00
codex: normalize apply_patch fs paths against symlinked ancestors
This commit is contained in:
@@ -163,12 +163,31 @@ impl ApplyPatchFileSystem for EnvironmentApplyPatchFileSystem {
|
||||
}
|
||||
|
||||
fn absolute_path(path: &std::path::Path) -> std::result::Result<AbsolutePathBuf, ApplyPatchError> {
|
||||
AbsolutePathBuf::from_absolute_path(path).map_err(|error| {
|
||||
let path = AbsolutePathBuf::from_absolute_path(path).map_err(|error| {
|
||||
ApplyPatchError::io_error(
|
||||
format!("Expected absolute path for apply_patch: {}", path.display()),
|
||||
io::Error::new(io::ErrorKind::InvalidInput, error.to_string()),
|
||||
)
|
||||
})
|
||||
})?;
|
||||
Ok(normalize_existing_ancestor_path(path))
|
||||
}
|
||||
|
||||
fn normalize_existing_ancestor_path(path: AbsolutePathBuf) -> AbsolutePathBuf {
|
||||
let raw_path = path.to_path_buf();
|
||||
for ancestor in raw_path.ancestors() {
|
||||
let Ok(canonical_ancestor) = ancestor.canonicalize() else {
|
||||
continue;
|
||||
};
|
||||
let Ok(suffix) = raw_path.strip_prefix(ancestor) else {
|
||||
continue;
|
||||
};
|
||||
if let Ok(normalized_path) =
|
||||
AbsolutePathBuf::from_absolute_path(canonical_ancestor.join(suffix))
|
||||
{
|
||||
return normalized_path;
|
||||
}
|
||||
}
|
||||
path
|
||||
}
|
||||
|
||||
pub(crate) async fn apply_patch(
|
||||
|
||||
@@ -31,6 +31,25 @@ fn convert_apply_patch_maps_add_variant() {
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
#[test]
|
||||
fn absolute_path_normalizes_existing_symlink_ancestor() {
|
||||
use std::os::unix::fs::symlink;
|
||||
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
let real_root = tmp.path().join("real");
|
||||
let link_root = tmp.path().join("link");
|
||||
std::fs::create_dir_all(&real_root).expect("create real root");
|
||||
symlink(&real_root, &link_root).expect("create symlink");
|
||||
|
||||
let path = link_root.join("nested").join("file.txt");
|
||||
let got = absolute_path(path.as_path()).expect("normalize absolute path");
|
||||
let expected = AbsolutePathBuf::from_absolute_path(real_root.join("nested/file.txt"))
|
||||
.expect("expected normalized path");
|
||||
|
||||
assert_eq!(got, expected);
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct RecordingExecutorFileSystem {
|
||||
raw_reads: Mutex<Vec<PathBuf>>,
|
||||
|
||||
Reference in New Issue
Block a user