From d364dc8b39095061ba930e713335d4398cc4d977 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Fri, 1 Apr 2016 14:33:42 +0200 Subject: [PATCH] ignore: don't use realpath to canonicalize path 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. --- src/ignore.c | 14 +++++++++++--- tests/attr/ignore.c | 13 +++++++++++++ 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"); +}