diff options
| author | Carlos Martín Nieto <carlosmn@github.com> | 2018-05-16 14:47:04 +0200 |
|---|---|---|
| committer | Carlos Martín Nieto <carlosmn@github.com> | 2018-05-18 14:49:08 +0200 |
| commit | 22973e099e85211470b6bc26c55d7cf9f7934079 (patch) | |
| tree | b84df1ba2c22333c11b055cb14ebcbca42e55959 /src/path.c | |
| parent | 0283fc4697988d1067946e781066da5fc1397175 (diff) | |
| download | libgit2-22973e099e85211470b6bc26c55d7cf9f7934079.tar.gz | |
path: provide a generic function for checking dogit files on NTFS
It checks against the 8.3 shortname variants, including the one which includes
the checksum as part of its name.
Diffstat (limited to 'src/path.c')
| -rw-r--r-- | src/path.c | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/src/path.c b/src/path.c index e770e530b..8c548746e 100644 --- a/src/path.c +++ b/src/path.c @@ -1621,6 +1621,59 @@ GIT_INLINE(bool) verify_dotgit_ntfs(git_repository *repo, const char *path, size return false; } +GIT_INLINE(bool) only_spaces_and_dots(const char *path) +{ + const char *c = path; + + for (;; c++) { + if (*c == '\0') + return true; + if (*c != ' ' && *c != '.') + return false; + } + + return true; +} + +GIT_INLINE(bool) verify_dotgit_ntfs_generic(const char *name, const char *dotgit_name, const char *shortname_pfix) +{ + size_t len = strlen(name); + size_t dotgit_len = strlen(dotgit_name); + int i, saw_tilde; + + if (name[0] == '.' && len >= dotgit_len && + !strncasecmp(name + 1, dotgit_name, dotgit_len)) { + return !only_spaces_and_dots(name + dotgit_len + 1); + } + + /* Detect the basic NTFS shortname with the first six chars */ + if (!strncasecmp(name, dotgit_name, 6) && name[6] == '~' && + name[7] >= '1' && name[7] <= '4') + return !only_spaces_and_dots(name + 8); + + /* Catch fallback names */ + for (i = 0, saw_tilde = 0; i < 8; i++) { + if (name[i] == '\0') { + return true; + } else if (saw_tilde) { + if (name[i] < '0' || name[i] > '9') + return true; + } else if (name[i] == '~') { + if (name[i+1] < '1' || name[i+1] > '9') + return true; + saw_tilde = 1; + } else if (i >= 6) { + return true; + } else if (name[i] < 0) { + return true; + } else if (git__tolower(name[i]) != shortname_pfix[i]) { + return true; + } + } + + return !only_spaces_and_dots(name + i); +} + GIT_INLINE(bool) verify_char(unsigned char c, unsigned int flags) { if ((flags & GIT_PATH_REJECT_BACKSLASH) && c == '\\') |
