mirror of
https://github.com/openai/codex.git
synced 2026-09-20 12:47:38 +00:00
fix: validate linked worktree trust metadata
This commit is contained in:
@@ -615,6 +615,11 @@ async fn resolve_root_git_project_for_trust_detects_worktree_pointer_without_git
|
||||
format!("gitdir: {}\n", worktree_git_dir.display()),
|
||||
)
|
||||
.unwrap();
|
||||
std::fs::write(
|
||||
worktree_git_dir.join("gitdir"),
|
||||
format!("{}\n", worktree_root.join(".git").display()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let expected = repo_root.abs();
|
||||
let worktree_root = worktree_root.abs();
|
||||
@@ -629,6 +634,30 @@ async fn resolve_root_git_project_for_trust_detects_worktree_pointer_without_git
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn resolve_root_git_project_for_trust_rejects_forged_worktree_pointer() {
|
||||
let tmp = TempDir::new().expect("tempdir");
|
||||
let trusted_repo = tmp.path().join("trusted");
|
||||
let forged_repo = tmp.path().join("forged");
|
||||
let forged_git_dir = trusted_repo
|
||||
.join(".git")
|
||||
.join("worktrees")
|
||||
.join("feature-x");
|
||||
std::fs::create_dir_all(&forged_git_dir).unwrap();
|
||||
std::fs::create_dir_all(&forged_repo).unwrap();
|
||||
std::fs::write(
|
||||
forged_repo.join(".git"),
|
||||
format!("gitdir: {}\n", forged_git_dir.display()),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert!(
|
||||
resolve_root_git_project_for_trust(LOCAL_FS.as_ref(), &forged_repo.abs())
|
||||
.await
|
||||
.is_none()
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn resolve_root_git_project_for_trust_non_worktrees_gitdir_returns_none() {
|
||||
let tmp = TempDir::new().expect("tempdir");
|
||||
|
||||
@@ -764,11 +764,41 @@ pub async fn resolve_root_git_project_for_trust(
|
||||
}
|
||||
|
||||
let git_dir_path = AbsolutePathBuf::resolve_path_against_base(git_dir_rel, repo_root.as_path());
|
||||
if !fs
|
||||
.get_metadata(&git_dir_path, /*sandbox*/ None)
|
||||
.await
|
||||
.ok()?
|
||||
.is_directory
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let worktrees_dir = git_dir_path.parent()?;
|
||||
if worktrees_dir.as_path().file_name() != Some(OsStr::new("worktrees")) {
|
||||
return None;
|
||||
}
|
||||
|
||||
// A linked worktree is valid only when its gitdir points back to this checkout's .git file.
|
||||
let git_dir_backref = fs
|
||||
.read_file_text(&git_dir_path.join("gitdir"), /*sandbox*/ None)
|
||||
.await
|
||||
.ok()?;
|
||||
let git_dir_backref = git_dir_backref.trim();
|
||||
if git_dir_backref.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let git_dir_backref_path =
|
||||
AbsolutePathBuf::resolve_path_against_base(git_dir_backref, git_dir_path.as_path());
|
||||
if fs
|
||||
.canonicalize(&git_dir_backref_path, /*sandbox*/ None)
|
||||
.await
|
||||
.ok()?
|
||||
!= fs.canonicalize(&dot_git, /*sandbox*/ None).await.ok()?
|
||||
{
|
||||
return None;
|
||||
}
|
||||
|
||||
let common_dir = worktrees_dir.parent()?;
|
||||
common_dir.parent()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user