Commit Diff


commit - 9c6f408e227e19f58acfc34e96b12d9de29581fd
commit + 692a4bb1222d6b7c94768d7305a2178a15b05887
blob - 29feb8935ab716a9191034d2ebede3da7cea1f73
blob + 4370083c6addb07677bb5bf8779721aad3c6fdec
--- got/got.c
+++ got/got.c
@@ -3077,6 +3077,15 @@ cmd_checkout(int argc, char *argv[])
 	got_path_strip_trailing_slashes(repo_path);
 	got_path_strip_trailing_slashes(worktree_path);
 
+	if (got_path_is_child(worktree_path, repo_path, strlen(repo_path)) ||
+	    got_path_is_child(repo_path, worktree_path,
+	    strlen(worktree_path))) {
+		error = got_error_fmt(GOT_ERR_BAD_PATH,
+		    "work tree and repository paths may not overlap: %s",
+		    worktree_path);
+		goto done;
+	}
+
 	error = got_repo_pack_fds_open(&pack_fds);
 	if (error != NULL)
 		goto done;
blob - 993c64afcbd5f4598770774738e513c4afb9387c
blob + 642aa7ff0a7ff201dae5e22b59ce99b7e725eced
--- regress/cmdline/checkout.sh
+++ regress/cmdline/checkout.sh
@@ -141,9 +141,77 @@ test_checkout_dir_not_empty() {
 	ret=$?
 	if [ $ret -ne 0 ]; then
 		diff -u $testroot/stdout.expected $testroot/stdout
+	fi
+	test_done "$testroot" "$ret"
+
+}
+
+test_checkout_into_repo() {
+	local testroot=`test_init checkout_into_repo`
+	local commit_id=`git_show_head $testroot/repo`
+
+	got checkout $testroot/repo $testroot/repo/wt \
+		> $testroot/stdout 2> $testroot/stderr
+	ret=$?
+	if [ $ret -eq 0 ]; then
+		echo "checkout succeeded unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	echo -n > $testroot/stdout.expected
+
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	echo -n "got: work tree and repository paths may not overlap: " \
+		> $testroot/stderr.expected
+	echo "$testroot/repo/wt: bad path" >> $testroot/stderr.expected
+	cmp -s $testroot/stderr.expected $testroot/stderr
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stderr.expected $testroot/stderr
 	fi
 	test_done "$testroot" "$ret"
+}
 
+test_checkout_overlap_repo() {
+	local testroot=`test_init checkout_into_repo`
+	local commit_id=`git_show_head $testroot/repo`
+
+	got checkout $testroot/repo $testroot \
+		> $testroot/stdout 2> $testroot/stderr
+	ret=$?
+	if [ $ret -eq 0 ]; then
+		echo "checkout succeeded unexpectedly" >&2
+		test_done "$testroot" "1"
+		return 1
+	fi
+
+	echo -n > $testroot/stdout.expected
+
+	cmp -s $testroot/stdout.expected $testroot/stdout
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stdout.expected $testroot/stdout
+		test_done "$testroot" "$ret"
+		return 1
+	fi
+
+	echo -n "got: work tree and repository paths may not overlap: " \
+		> $testroot/stderr.expected
+	echo "$testroot: bad path" >> $testroot/stderr.expected
+	cmp -s $testroot/stderr.expected $testroot/stderr
+	ret=$?
+	if [ $ret -ne 0 ]; then
+		diff -u $testroot/stderr.expected $testroot/stderr
+	fi
+	test_done "$testroot" "$ret"
 }
 
 test_checkout_sets_xbit() {
@@ -1010,6 +1078,8 @@ test_parseargs "$@"
 run_test test_checkout_basic
 run_test test_checkout_dir_exists
 run_test test_checkout_dir_not_empty
+run_test test_checkout_into_repo
+run_test test_checkout_overlap_repo
 run_test test_checkout_sets_xbit
 run_test test_checkout_commit_from_wrong_branch
 run_test test_checkout_tag