summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2016-04-01 14:33:42 +0200
committerCarlos Martín Nieto <carlosmn@github.com>2016-04-02 21:32:28 +0200
commitd364dc8b39095061ba930e713335d4398cc4d977 (patch)
tree518081177e5e6913a33b531855390c14465617dd
parent36fc25572ca042372b1a58f07bc721b2b827e8be (diff)
downloadlibgit2-cmn/ignore-symlink.tar.gz
ignore: don't use realpath to canonicalize pathcmn/ignore-symlink
If we're looking for a symlink, realpath will give us the resolved path, which is not what we're after, but a canonicalized version of the path the user asked for.
-rw-r--r--src/ignore.c14
-rw-r--r--tests/attr/ignore.c13
2 files changed, 24 insertions, 3 deletions
diff --git a/src/ignore.c b/src/ignore.c
index aedc1401e..ac2af4f58 100644
--- a/src/ignore.c
+++ b/src/ignore.c
@@ -263,10 +263,18 @@ int git_ignore__for_path(
goto cleanup;
/* given a unrooted path in a non-bare repo, resolve it */
- if (workdir && git_path_root(path) < 0)
- error = git_path_find_dir(&ignores->dir, path, workdir);
- else
+ if (workdir && git_path_root(path) < 0) {
+ git_buf local = GIT_BUF_INIT;
+
+ if ((error = git_path_dirname_r(&local, path)) < 0 ||
+ (error = git_path_resolve_relative(&local, 0)) < 0 ||
+ (error = git_path_to_dir(&local)) < 0 ||
+ (error = git_buf_joinpath(&ignores->dir, workdir, local.ptr)) < 0)
+ {;} /* Nothing, we just want to stop on the first error */
+ git_buf_free(&local);
+ } else {
error = git_buf_joinpath(&ignores->dir, path, "");
+ }
if (error < 0)
goto cleanup;
diff --git a/tests/attr/ignore.c b/tests/attr/ignore.c
index 27fed2539..91bf984a1 100644
--- a/tests/attr/ignore.c
+++ b/tests/attr/ignore.c
@@ -252,3 +252,16 @@ void test_attr_ignore__dont_ignore_files_for_folder(void)
if (cl_repo_get_bool(g_repo, "core.ignorecase"))
assert_is_ignored(false, "dir/TeSt");
}
+
+void test_attr_ignore__symlink_to_outside(void)
+{
+#ifdef GIT_WIN32
+ cl_skip();
+#endif
+
+ cl_git_rewritefile("attr/.gitignore", "symlink\n");
+ cl_git_mkfile("target", "target");
+ cl_git_pass(p_symlink("../target", "attr/symlink"));
+ assert_is_ignored(true, "symlink");
+ assert_is_ignored(true, "lala/../symlink");
+}