[PATCH v3 7/8] normalize_ceiling_entry(): resolve symlinks
- From
Michael Haggerty <mhagger@alum.mit.edu>
- Date
- Oct 21, 2012, 05:57 UTC
- Message-ID
- <1350799057-13846-8-git-send-email-mhagger@alum.mit.edu>
- In-Reply-To
- <1350799057-13846-1-git-send-email-mhagger@alum.mit.edu>
longest_ancestor_length() relies on a textual comparison of directory parts to find the part of path that overlaps with one of the paths in prefix_list. But this doesn't work if any of the prefixes involves a symbolic link, because the directories will look different even though they might logically refer to the same directory. So canonicalize the paths listed in GIT_CEILING_DIRECTORIES using real_path_if_valid() before passing them to longest_ancestor_length().
path is already in canonical form, so doesn't need to be canonicalized again.
This fixes some problems with using GIT_CEILING_DIRECTORIES that contains paths involving symlinks, including t4035 if run with --root set to a path involving symlinks.
Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> --- setup.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-)
diff --git a/setup.c b/setup.c index df97ad3..2eb5b75 100644 --- a/setup.c +++ b/setup.c @@ -622,24 +622,22 @@ static dev_t get_device_or_die(const char *path, const char *prefix, int prefix_ } /* - * A "string_list_each_func_t" function that normalizes an entry from - * GIT_CEILING_DIRECTORIES or discards it if unusable. + * A "string_list_each_func_t" function that canonicalizes an entry + * from GIT_CEILING_DIRECTORIES using real_path_if_valid(), or + * discards it if unusable. */ static int normalize_ceiling_entry(struct string_list_item *item, void *unused) { - const char *ceil = item->string; - int len = strlen(ceil); - char buf[PATH_MAX+1]; + char *ceil = item->string; + const char *real_path; - if (len == 0 || len > PATH_MAX || !is_absolute_path(ceil)) + if (!*ceil || !is_absolute_path(ceil)) return 0; - if (normalize_path_copy(buf, ceil) < 0) + real_path = real_path_if_valid(ceil); + if (!real_path) return 0; - len = strlen(buf); - if (len > 1 && buf[len-1] == '/') - buf[--len] = '\0'; free(item->string); - item->string = xstrdup(buf); + item->string = xstrdup(real_path); return 1; }
-- 1.7.11.3