commit - b15bc87b1884e0d5a69df4536d29a8a8af8a745b
commit + 906c123b76844b1bba457451f3571b64afa77006
blob - be2544b20e495c1e8e6ec3d59412f2024401e94a
blob + 879e8cb6f14e7b6c5f1c156dc33f16a2e9710324
--- lib/worktree.c
+++ lib/worktree.c
char target_path[PATH_MAX];
size_t len, target_len = 0;
char *resolved_path = NULL, *abspath = NULL;
+ char *path_got = NULL;
const uint8_t *buf = got_object_blob_get_read_buf(blob);
size_t hdrlen = got_object_blob_get_hdrlen(blob);
goto done;
}
+ /* Do not allow symlinks pointing into the .got directory. */
+ if (asprintf(&path_got, "%s/%s", worktree->root_path,
+ GOT_WORKTREE_GOT_DIR) == -1) {
+ err = got_error_from_errno("asprintf");
+ goto done;
+ }
+ if (got_path_is_child(resolved_path ? resolved_path : (abspath ?
+ abspath : target_path), path_got, strlen(path_got))) {
+ /* install as a regular file */
+ got_object_blob_rewind(blob);
+ err = install_blob(worktree, ondisk_path, path,
+ GOT_DEFAULT_FILE_MODE, st_mode, blob,
+ restoring_missing_file, reverting_versioned_file,
+ repo, progress_cb, progress_arg);
+ goto done;
+ }
+
if (symlink(target_path, ondisk_path) == -1) {
if (errno == EEXIST) {
struct stat sb;
done:
free(resolved_path);
free(abspath);
+ free(path_got);
return err;
}
blob - 6cde66bae40dff4c5b2cb46b31fe7b2ca5f1df13
blob + a7cf8346fb69dcd9589570531e799d90564c3ee0
--- regress/cmdline/checkout.sh
+++ regress/cmdline/checkout.sh
(cd $testroot/repo && ln -s /etc/passwd passwd.link)
(cd $testroot/repo && ln -s ../beta epsilon/beta.link)
(cd $testroot/repo && ln -s nonexistent nonexistent.link)
+ (cd $testroot/repo && ln -s .got/foo dotgotfoo.link)
(cd $testroot/repo && git add .)
git_commit $testroot/repo -m "add symlinks"
ret="$?"
if [ "$ret" != "0" ]; then
diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
fi
+
+ if [ -h $testroot/wt/dotgotfoo.link ]; then
+ echo -n "dotgotfoo.link symlink points into .got dir: " >&2
+ readlink $testroot/wt/dotgotfoo.link >&2
+ test_done "$testroot" "1"
+ return 1
+ fi
+
+ echo -n ".got/foo" > $testroot/content.expected
+ cp $testroot/wt/dotgotfoo.link $testroot/content
+
+ cmp -s $testroot/content.expected $testroot/content
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/content.expected $testroot/content
+ fi
test_done "$testroot" "$ret"
}