diff options
author | Junio C Hamano <gitster@pobox.com> | 2018-05-22 14:10:49 +0900 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2018-05-22 14:10:49 +0900 |
commit | 7b01c71b64d25202d80b73cbd46104ebfddbdab3 (patch) | |
tree | 98de7ee189397c8e539459ed1a699be47cc0bff3 /read-cache.c | |
parent | Git 2.14.3 (diff) | |
parent | Git 2.13.7 (diff) | |
download | tgif-7b01c71b64d25202d80b73cbd46104ebfddbdab3.tar.xz |
Sync with Git 2.13.7
* maint-2.13:
Git 2.13.7
verify_path: disallow symlinks in .gitmodules
update-index: stat updated files earlier
verify_dotfile: mention case-insensitivity in comment
verify_path: drop clever fallthrough
skip_prefix: add case-insensitive variant
is_{hfs,ntfs}_dotgitmodules: add tests
is_ntfs_dotgit: match other .git files
is_hfs_dotgit: match other .git files
is_ntfs_dotgit: use a size_t for traversing string
submodule-config: verify submodule names as paths
Diffstat (limited to 'read-cache.c')
-rw-r--r-- | read-cache.c | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/read-cache.c b/read-cache.c index 5e6d24d444..5b57b369e8 100644 --- a/read-cache.c +++ b/read-cache.c @@ -732,7 +732,7 @@ struct cache_entry *make_cache_entry(unsigned int mode, int size, len; struct cache_entry *ce, *ret; - if (!verify_path(path)) { + if (!verify_path(path, mode)) { error("Invalid path '%s'", path); return NULL; } @@ -796,7 +796,7 @@ int ce_same_name(const struct cache_entry *a, const struct cache_entry *b) * Also, we don't want double slashes or slashes at the * end that can make pathnames ambiguous. */ -static int verify_dotfile(const char *rest) +static int verify_dotfile(const char *rest, unsigned mode) { /* * The first character was '.', but that @@ -810,8 +810,13 @@ static int verify_dotfile(const char *rest) switch (*rest) { /* - * ".git" followed by NUL or slash is bad. This - * shares the path end test with the ".." case. + * ".git" followed by NUL or slash is bad. Note that we match + * case-insensitively here, even if ignore_case is not set. + * This outlaws ".GIT" everywhere out of an abundance of caution, + * since there's really no good reason to allow it. + * + * Once we've seen ".git", we can also find ".gitmodules", etc (also + * case-insensitively). */ case 'g': case 'G': @@ -819,8 +824,15 @@ static int verify_dotfile(const char *rest) break; if (rest[2] != 't' && rest[2] != 'T') break; - rest += 2; - /* fallthrough */ + if (rest[3] == '\0' || is_dir_sep(rest[3])) + return 0; + if (S_ISLNK(mode)) { + rest += 3; + if (skip_iprefix(rest, "modules", &rest) && + (*rest == '\0' || is_dir_sep(*rest))) + return 0; + } + break; case '.': if (rest[1] == '\0' || is_dir_sep(rest[1])) return 0; @@ -828,7 +840,7 @@ static int verify_dotfile(const char *rest) return 1; } -int verify_path(const char *path) +int verify_path(const char *path, unsigned mode) { char c; @@ -841,12 +853,25 @@ int verify_path(const char *path) return 1; if (is_dir_sep(c)) { inside: - if (protect_hfs && is_hfs_dotgit(path)) - return 0; - if (protect_ntfs && is_ntfs_dotgit(path)) - return 0; + if (protect_hfs) { + if (is_hfs_dotgit(path)) + return 0; + if (S_ISLNK(mode)) { + if (is_hfs_dotgitmodules(path)) + return 0; + } + } + if (protect_ntfs) { + if (is_ntfs_dotgit(path)) + return 0; + if (S_ISLNK(mode)) { + if (is_ntfs_dotgitmodules(path)) + return 0; + } + } + c = *path++; - if ((c == '.' && !verify_dotfile(path)) || + if ((c == '.' && !verify_dotfile(path, mode)) || is_dir_sep(c) || c == '\0') return 0; } @@ -1163,7 +1188,7 @@ static int add_index_entry_with_check(struct index_state *istate, struct cache_e if (!ok_to_add) return -1; - if (!verify_path(ce->name)) + if (!verify_path(ce->name, ce->ce_mode)) return error("Invalid path '%s'", ce->name); if (!skip_df_check && |