Skip to content

Commit

Permalink
Assure that Project::path can be compared reasonably with other pat…
Browse files Browse the repository at this point in the history
…hs (gitbutlerapp#5096)

When testing paths for prefix-matches it's important they are all normalized in
the same fashion.

`canonicalize()` is very particular about canonicalizing Windows paths, which
makes it easy for these paths to not be compatible to other absolute-looking
paths.

The difficulty here is to get the right trade-off between performance and
safety, e.g. we wouldn't want these canonicalized Windows paths to be used
anywhere as they are very uncommon (and don't even work everywhere).
  • Loading branch information
Byron committed Oct 11, 2024
1 parent b58a3f6 commit d63babf
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 18 deletions.
2 changes: 1 addition & 1 deletion crates/gitbutler-project/src/controller.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl Controller {
let project = Project {
id: ProjectId::generate(),
title,
path: path.to_path_buf(),
path: gix::path::realpath(path)?,
api: None,
..Default::default()
};
Expand Down
33 changes: 16 additions & 17 deletions crates/gitbutler-repo/src/commands.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,25 +49,24 @@ impl RepoCommands for Project {

fn read_file_from_workspace(&self, relative_path: &Path) -> Result<String> {
let ctx = CommandContext::open(self)?;
if self
.path
.join(relative_path)
.canonicalize()?
.as_path()
.starts_with(self.path.clone())
{
let tree = ctx.repository().head()?.peel_to_tree()?;
let entry = tree.get_path(relative_path)?;
let blob = ctx.repository().find_blob(entry.id())?;
let path_in_worktree = gix::path::realpath(self.path.join(relative_path))?;
if !path_in_worktree.starts_with(self.path.clone()) {
anyhow::bail!(
"Path to read from at '{}' isn't in the worktree directory '{}'",
relative_path.display(),
self.path.display()
);
}

let tree = ctx.repository().head()?.peel_to_tree()?;
let entry = tree.get_path(relative_path)?;
let blob = ctx.repository().find_blob(entry.id())?;

if !blob.is_binary() {
let content = std::str::from_utf8(blob.content())?;
Ok(content.to_string())
} else {
anyhow::bail!("File is binary");
}
if !blob.is_binary() {
let content = std::str::from_utf8(blob.content())?;
Ok(content.to_string())
} else {
anyhow::bail!("Invalid workspace file");
anyhow::bail!("File is binary");
}
}
}

0 comments on commit d63babf

Please sign in to comment.