use crate::common::{
TestRepo, configure_directive_files, directive_files, repo, setup_snapshot_settings, wt_command,
};
use insta::Settings;
use insta_cmd::assert_cmd_snapshot;
use rstest::rstest;
use std::process::Command;
#[rstest]
fn test_git_rejects_nul_in_commit_messages(repo: TestRepo) {
use std::process::Stdio;
let malicious_message = "Fix bug\0__WORKTRUNK_EXEC__echo PWNED";
std::fs::write(repo.root_path().join("test.txt"), "content").unwrap();
repo.run_git(&["add", "."]);
let shell_cmd = format!(
"printf '{}' | git commit -F -",
malicious_message.replace('\0', r"\0")
);
let mut cmd = Command::new("sh");
repo.configure_git_cmd(&mut cmd);
cmd.arg("-c")
.arg(&shell_cmd)
.current_dir(repo.root_path())
.stdout(Stdio::null())
.stderr(Stdio::piped());
let output = cmd.output().unwrap();
assert!(
!output.status.success(),
"Expected git to reject NUL bytes in commit message"
);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
stderr.contains("NUL byte") || stderr.contains("nul byte"),
"Expected git to complain about NUL bytes, got: {}",
stderr
);
}
#[rstest]
fn test_rust_prevents_nul_bytes_in_args(repo: TestRepo) {
let malicious_branch = "feature\0__WORKTRUNK_EXEC__echo PWNED";
let result = repo.git_command().args(["branch", malicious_branch]).run();
match result {
Err(e) if e.kind() == std::io::ErrorKind::InvalidInput => {
}
Ok(output) => {
panic!(
"Expected Rust to reject NUL bytes in args, but command succeeded: {:?}",
output
);
}
Err(e) => {
panic!(
"Expected InvalidInput error for NUL bytes, got different error: {:?}",
e
);
}
}
}
#[rstest]
fn test_branch_name_is_directive_not_executed(repo: TestRepo) {
let malicious_branch = "__WORKTRUNK_EXEC__echo PWNED > /tmp/hacked2";
let result = repo
.git_command()
.args(["branch", malicious_branch])
.run()
.unwrap();
if !result.status.success() {
return;
}
let mut settings = Settings::clone_current();
settings.set_snapshot_path("../snapshots");
settings.bind(|| {
let (cd_path, exec_path, _guard) = directive_files();
let mut cmd = wt_command();
repo.configure_wt_cmd(&mut cmd);
configure_directive_files(&mut cmd, &cd_path, &exec_path);
cmd.arg("switch")
.arg("--create")
.arg(malicious_branch)
.current_dir(repo.root_path());
assert_cmd_snapshot!(cmd);
});
assert!(
!std::path::Path::new("/tmp/hacked2").exists(),
"Malicious code was executed! File /tmp/hacked2 should not exist"
);
}
#[rstest]
fn test_branch_name_with_newline_directive_not_executed(repo: TestRepo) {
let malicious_branch = "feature\n__WORKTRUNK_EXEC__echo PWNED > /tmp/hacked3";
let result = repo
.git_command()
.args(["branch", malicious_branch])
.run()
.unwrap();
if !result.status.success() {
return;
}
let mut settings = Settings::clone_current();
settings.set_snapshot_path("../snapshots");
settings.bind(|| {
let (cd_path, exec_path, _guard) = directive_files();
let mut cmd = wt_command();
repo.configure_wt_cmd(&mut cmd);
configure_directive_files(&mut cmd, &cd_path, &exec_path);
cmd.arg("switch")
.arg("--create")
.arg(malicious_branch)
.current_dir(repo.root_path());
assert_cmd_snapshot!(cmd);
});
assert!(
!std::path::Path::new("/tmp/hacked3").exists(),
"Malicious code was executed!"
);
}
#[rstest]
fn test_commit_message_with_directive_not_executed(mut repo: TestRepo) {
let malicious_message = "Fix bug\n__WORKTRUNK_EXEC__echo PWNED > /tmp/hacked4";
repo.commit_with_message(malicious_message);
let _feature_wt = repo.add_worktree("feature");
let mut settings = setup_snapshot_settings(&repo);
settings.add_filter(r"\b[0-9a-f]{7,40}\b", "[SHA]");
settings.bind(|| {
let mut cmd = wt_command();
repo.configure_wt_cmd(&mut cmd);
cmd.arg("list").current_dir(repo.root_path());
assert_cmd_snapshot!(cmd);
});
assert!(
!std::path::Path::new("/tmp/hacked4").exists(),
"Malicious code was executed from commit message!"
);
}
#[cfg(unix)]
#[rstest]
fn test_path_with_directive_not_executed(repo: TestRepo) {
let malicious_dir = repo
.root_path()
.join("__WORKTRUNK_EXEC__echo PWNED > /tmp/hacked5");
std::fs::create_dir_all(&malicious_dir).unwrap();
let settings = setup_snapshot_settings(&repo);
settings.bind(|| {
let mut cmd = wt_command();
repo.configure_wt_cmd(&mut cmd);
cmd.arg("list").current_dir(repo.root_path());
assert_cmd_snapshot!(cmd);
});
assert!(
!std::path::Path::new("/tmp/hacked5").exists(),
"Malicious code was executed from path display!"
);
}
#[rstest]
fn test_branch_name_with_cd_directive_not_executed(repo: TestRepo) {
let malicious_branch = "__WORKTRUNK_CD__/tmp";
let result = repo
.git_command()
.args(["branch", malicious_branch])
.run()
.unwrap();
if !result.status.success() {
return;
}
let settings = setup_snapshot_settings(&repo);
settings.bind(|| {
let (cd_path, exec_path, _guard) = directive_files();
let mut cmd = wt_command();
repo.configure_wt_cmd(&mut cmd);
configure_directive_files(&mut cmd, &cd_path, &exec_path);
cmd.arg("switch")
.arg("--create")
.arg(malicious_branch)
.current_dir(repo.root_path());
assert_cmd_snapshot!(cmd);
});
}
#[rstest]
fn test_error_message_with_directive_not_executed(repo: TestRepo) {
let malicious_branch = "__WORKTRUNK_EXEC__echo PWNED > /tmp/hacked6";
let settings = setup_snapshot_settings(&repo);
settings.bind(|| {
let (cd_path, exec_path, _guard) = directive_files();
let mut cmd = wt_command();
repo.configure_wt_cmd(&mut cmd);
configure_directive_files(&mut cmd, &cd_path, &exec_path);
cmd.arg("switch")
.arg(malicious_branch)
.current_dir(repo.root_path());
assert_cmd_snapshot!(cmd);
});
assert!(
!std::path::Path::new("/tmp/hacked6").exists(),
"Malicious code was executed from error message!"
);
}
#[rstest]
fn test_execute_flag_with_directive_like_branch_name(repo: TestRepo) {
let malicious_branch = "__WORKTRUNK_EXEC__echo PWNED > /tmp/hacked7";
let result = repo
.git_command()
.args(["branch", malicious_branch])
.run()
.unwrap();
if !result.status.success() {
return;
}
let mut settings = Settings::clone_current();
settings.set_snapshot_path("../snapshots");
settings.bind(|| {
let (cd_path, exec_path, _guard) = directive_files();
let mut cmd = wt_command();
repo.configure_wt_cmd(&mut cmd);
configure_directive_files(&mut cmd, &cd_path, &exec_path);
cmd.arg("switch")
.arg("--create")
.arg(malicious_branch)
.arg("-x")
.arg("echo legitimate command")
.current_dir(repo.root_path());
assert_cmd_snapshot!(cmd);
});
assert!(
!std::path::Path::new("/tmp/hacked7").exists(),
"Malicious code was executed alongside legitimate -x command!"
);
}
#[rstest]
#[cfg(unix)]
fn test_git_rejects_ansi_escape_in_branch_names(repo: TestRepo) {
let shell_cmd = r#"git branch $'feature-\x1b[31mRED\x1b[0m-test'"#;
let output = Command::new("bash")
.args(["-c", shell_cmd])
.current_dir(repo.root_path())
.output()
.unwrap();
assert!(
!output.status.success(),
"Expected git to reject ANSI escape sequences in branch name"
);
let stderr = String::from_utf8_lossy(&output.stderr);
assert!(
stderr.contains("not a valid branch name") || stderr.contains("invalid"),
"Expected git to complain about invalid branch name, got: {}",
stderr
);
}
#[rstest]
#[cfg(unix)]
fn test_git_ignores_malformed_refs_with_ansi(repo: TestRepo) {
let shell_cmd = r#"
commit_sha=$(git rev-parse HEAD)
printf "$commit_sha" > '.git/refs/heads/feature-'$'\x1b''[31mRED'$'\x1b''[0m-test'
"#;
let create_result = Command::new("bash")
.args(["-c", shell_cmd])
.current_dir(repo.root_path())
.output()
.unwrap();
assert!(
create_result.status.success(),
"Failed to create malformed ref file: {}",
String::from_utf8_lossy(&create_result.stderr)
);
let branch_output = repo.git_output(&["branch", "-a"]);
assert!(
!branch_output.contains("RED"),
"Malformed ref with ANSI escape should not appear in branch list"
);
let settings = setup_snapshot_settings(&repo);
settings.bind(|| {
let mut cmd = wt_command();
repo.configure_wt_cmd(&mut cmd);
cmd.arg("list").current_dir(repo.root_path());
assert_cmd_snapshot!(cmd);
});
}
#[rstest]
fn test_literal_escape_like_branch_names_displayed_safely(repo: TestRepo) {
let branch_name = "fix-backslash-x1b-test";
let result = repo.git_command().args(["branch", branch_name]).run();
if let Ok(output) = result
&& output.status.success()
{
let mut settings = setup_snapshot_settings(&repo);
settings.add_filter(r"\b[0-9a-f]{7,40}\b", "[SHA]");
settings.bind(|| {
let mut cmd = wt_command();
repo.configure_wt_cmd(&mut cmd);
cmd.args(["list", "--branches"])
.current_dir(repo.root_path());
assert_cmd_snapshot!(cmd);
});
}
}