Skip to content

Commit 1b77d83

Browse files
mhaggerpeff
authored andcommitted
setup_git_directory_gently_1(): resolve symlinks in ceiling paths
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(). (Also rename normalize_ceiling_entry() to canonicalize_ceiling_entry() to reflect the change.) 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. Please note that test t0060 is *not* changed analogously, because that would make the test suite results dependent on the contents of the local root directory. However, real_path() is already tested independently, and the "ancestor" tests cover the non-normalization aspects of longest_ancestor_length(), so coverage remains sufficient. Signed-off-by: Michael Haggerty <[email protected]> Signed-off-by: Jeff King <[email protected]>
1 parent 9e2326c commit 1b77d83

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

setup.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -622,24 +622,23 @@ static dev_t get_device_or_die(const char *path, const char *prefix, int prefix_
622622
}
623623

624624
/*
625-
* A "string_list_each_func_t" function that normalizes an entry from
626-
* GIT_CEILING_DIRECTORIES or discards it if unusable.
625+
* A "string_list_each_func_t" function that canonicalizes an entry
626+
* from GIT_CEILING_DIRECTORIES using real_path_if_valid(), or
627+
* discards it if unusable.
627628
*/
628-
static int normalize_ceiling_entry(struct string_list_item *item, void *unused)
629+
static int canonicalize_ceiling_entry(struct string_list_item *item,
630+
void *unused)
629631
{
630-
const char *ceil = item->string;
631-
int len = strlen(ceil);
632-
char buf[PATH_MAX+1];
632+
char *ceil = item->string;
633+
const char *real_path;
633634

634-
if (len == 0 || len > PATH_MAX || !is_absolute_path(ceil))
635+
if (!*ceil || !is_absolute_path(ceil))
635636
return 0;
636-
if (normalize_path_copy(buf, ceil) < 0)
637+
real_path = real_path_if_valid(ceil);
638+
if (!real_path)
637639
return 0;
638-
len = strlen(buf);
639-
if (len > 1 && buf[len-1] == '/')
640-
buf[--len] = '\0';
641640
free(item->string);
642-
item->string = xstrdup(buf);
641+
item->string = xstrdup(real_path);
643642
return 1;
644643
}
645644

@@ -681,7 +680,8 @@ static const char *setup_git_directory_gently_1(int *nongit_ok)
681680

682681
if (env_ceiling_dirs) {
683682
string_list_split(&ceiling_dirs, env_ceiling_dirs, PATH_SEP, -1);
684-
filter_string_list(&ceiling_dirs, 0, normalize_ceiling_entry, NULL);
683+
filter_string_list(&ceiling_dirs, 0,
684+
canonicalize_ceiling_entry, NULL);
685685
ceil_offset = longest_ancestor_length(cwd, &ceiling_dirs);
686686
string_list_clear(&ceiling_dirs, 0);
687687
}

0 commit comments

Comments
 (0)