-
Notifications
You must be signed in to change notification settings - Fork 322
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
local_working_copy: do not create file or write in directory named .j…
…j or .git I originally considered adding deny-list-based implementation, but the Windows compatibility rules are super confusing and I don't have a machine to find out possible aliases. This patch instead adds directory equivalence tests. In order to test file entity equivalence, we first need to create a file or directory of the requested name. It's harmless to create an empty .jj or .git directory, but materializing .git file or symlink can temporarily set up RCE situation. That's why new empty file is created to test the path validity. We might want to add some optimization for safe names (e.g. ASCII, not contain "git" or "jj", not contain "~", etc.) That being said, I'm not pretty sure if .git/.jj in sub directory must be checked. It's not safe to cd into the directory and run "jj", but the same thing can be said to other tools such as "cargo". Perhaps, our minimum requirement is to protect our metadata (= the root .jj and .git) directories. Despite the crate name (and internal use of std::fs::File), same_file::is_same_file() can test equivalence of directories. This is documented and tested, so I've removed my custom implementation, which was slightly simpler but lacks Windows support.
- Loading branch information
1 parent
eaafde7
commit ded48ff
Showing
5 changed files
with
415 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,12 +21,16 @@ use crate::common::get_stdout_string; | |
use crate::common::TestEnvironment; | ||
|
||
fn set_up_non_empty_git_repo(git_repo: &git2::Repository) { | ||
set_up_git_repo_with_file(git_repo, "file"); | ||
} | ||
|
||
fn set_up_git_repo_with_file(git_repo: &git2::Repository, filename: &str) { | ||
let signature = | ||
git2::Signature::new("Some One", "[email protected]", &git2::Time::new(0, 0)).unwrap(); | ||
let mut tree_builder = git_repo.treebuilder(None).unwrap(); | ||
let file_oid = git_repo.blob(b"content").unwrap(); | ||
tree_builder | ||
.insert("file", file_oid, git2::FileMode::Blob.into()) | ||
.insert(filename, file_oid, git2::FileMode::Blob.into()) | ||
.unwrap(); | ||
let tree_oid = tree_builder.write().unwrap(); | ||
let tree = git_repo.find_tree(tree_oid).unwrap(); | ||
|
@@ -577,6 +581,53 @@ fn test_git_clone_with_depth() { | |
"#); | ||
} | ||
|
||
#[test] | ||
fn test_git_clone_malformed() { | ||
let test_env = TestEnvironment::default(); | ||
let git_repo_path = test_env.env_root().join("source"); | ||
let git_repo = git2::Repository::init(git_repo_path).unwrap(); | ||
let clone_path = test_env.env_root().join("clone"); | ||
// libgit2 doesn't allow to create a malformed repo containing ".git", etc., | ||
// but we can insert ".jj" entry. | ||
set_up_git_repo_with_file(&git_repo, ".jj"); | ||
|
||
// TODO: Perhaps, this should be a user error, not an internal error. | ||
let stderr = | ||
test_env.jj_cmd_internal_error(test_env.env_root(), &["git", "clone", "source", "clone"]); | ||
insta::assert_snapshot!(stderr, @r#" | ||
Fetching into new repo in "$TEST_ENV/clone" | ||
bookmark: main@origin [new] untracked | ||
Setting the revset alias "trunk()" to "main@origin" | ||
Internal error: Failed to check out commit 039a1eae03465fd3be0fbad87c9ca97303742677 | ||
Caused by: Reserved path component .jj in $TEST_ENV/clone/.jj | ||
"#); | ||
|
||
// The cloned workspace isn't usable. | ||
let stderr = test_env.jj_cmd_failure(&clone_path, &["status"]); | ||
insta::assert_snapshot!(stderr, @r##" | ||
Error: The working copy is stale (not updated since operation 4a8ddda0ff63). | ||
Hint: Run `jj workspace update-stale` to update it. | ||
See https://martinvonz.github.io/jj/latest/working-copy/#stale-working-copy for more information. | ||
"##); | ||
|
||
// The error can be somehow recovered. | ||
// TODO: add an update-stale flag to reset the working-copy? | ||
let stderr = test_env.jj_cmd_internal_error(&clone_path, &["workspace", "update-stale"]); | ||
insta::assert_snapshot!(stderr, @r#" | ||
Internal error: Failed to check out commit 039a1eae03465fd3be0fbad87c9ca97303742677 | ||
Caused by: Reserved path component .jj in $TEST_ENV/clone/.jj | ||
"#); | ||
let (_stdout, stderr) = | ||
test_env.jj_cmd_ok(&clone_path, &["new", "root()", "--ignore-working-copy"]); | ||
insta::assert_snapshot!(stderr, @""); | ||
let stdout = test_env.jj_cmd_success(&clone_path, &["status"]); | ||
insta::assert_snapshot!(stdout, @r#" | ||
The working copy is clean | ||
Working copy : zsuskuln f652c321 (empty) (no description set) | ||
Parent commit: zzzzzzzz 00000000 (empty) (no description set) | ||
"#); | ||
} | ||
|
||
fn get_bookmark_output(test_env: &TestEnvironment, repo_path: &Path) -> String { | ||
test_env.jj_cmd_success(repo_path, &["bookmark", "list", "--all-remotes"]) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.