diff options
-rw-r--r-- | abspath.c | 4 | ||||
-rw-r--r-- | cache.h | 2 | ||||
-rw-r--r-- | compat/mingw.h | 9 | ||||
-rw-r--r-- | git-compat-util.h | 4 | ||||
-rw-r--r-- | read-cache.c | 25 |
5 files changed, 27 insertions, 17 deletions
@@ -40,7 +40,7 @@ const char *real_path(const char *path) while (depth--) { if (!is_directory(buf)) { - char *last_slash = strrchr(buf, '/'); + char *last_slash = find_last_dir_sep(buf); if (last_slash) { *last_slash = '\0'; last_elem = xstrdup(last_slash + 1); @@ -65,7 +65,7 @@ const char *real_path(const char *path) if (len + strlen(last_elem) + 2 > PATH_MAX) die ("Too long path name: '%s/%s'", buf, last_elem); - if (len && buf[len-1] != '/') + if (len && !is_dir_sep(buf[len-1])) buf[len++] = '/'; strcpy(buf + len, last_elem); free(last_elem); @@ -747,7 +747,7 @@ extern char *expand_user_path(const char *path); char *enter_repo(char *path, int strict); static inline int is_absolute_path(const char *path) { - return path[0] == '/' || has_dos_drive_prefix(path); + return is_dir_sep(path[0]) || has_dos_drive_prefix(path); } int is_directory(const char *); const char *real_path(const char *path); diff --git a/compat/mingw.h b/compat/mingw.h index 547568b91..ce9dd980e 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -300,6 +300,15 @@ int winansi_fprintf(FILE *stream, const char *format, ...) __attribute__((format #define has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':') #define is_dir_sep(c) ((c) == '/' || (c) == '\\') +static inline char *mingw_find_last_dir_sep(const char *path) +{ + char *ret = NULL; + for (; *path; ++path) + if (is_dir_sep(*path)) + ret = (char *)path; + return ret; +} +#define find_last_dir_sep mingw_find_last_dir_sep #define PATH_SEP ';' #define PRIuMAX "I64u" diff --git a/git-compat-util.h b/git-compat-util.h index e0bb81ed8..a75530df7 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -215,6 +215,10 @@ extern char *gitbasename(char *); #define is_dir_sep(c) ((c) == '/') #endif +#ifndef find_last_dir_sep +#define find_last_dir_sep(path) strrchr(path, '/') +#endif + #if __HP_cc >= 61000 #define NORETURN __attribute__((noreturn)) #define NORETURN_PTR diff --git a/read-cache.c b/read-cache.c index 4ac9a037f..46a9e6070 100644 --- a/read-cache.c +++ b/read-cache.c @@ -726,11 +726,12 @@ static int verify_dotfile(const char *rest) * has already been discarded, we now test * the rest. */ - switch (*rest) { + /* "." is not allowed */ - case '\0': case '/': + if (*rest == '\0' || is_dir_sep(*rest)) return 0; + switch (*rest) { /* * ".git" followed by NUL or slash is bad. This * shares the path end test with the ".." case. @@ -743,7 +744,7 @@ static int verify_dotfile(const char *rest) rest += 2; /* fallthrough */ case '.': - if (rest[1] == '\0' || rest[1] == '/') + if (rest[1] == '\0' || is_dir_sep(rest[1])) return 0; } return 1; @@ -753,23 +754,19 @@ int verify_path(const char *path) { char c; + if (has_dos_drive_prefix(path)) + return 0; + goto inside; for (;;) { if (!c) return 1; - if (c == '/') { + if (is_dir_sep(c)) { inside: c = *path++; - switch (c) { - default: - continue; - case '/': case '\0': - break; - case '.': - if (verify_dotfile(path)) - continue; - } - return 0; + if ((c == '.' && !verify_dotfile(path)) || + is_dir_sep(c) || c == '\0') + return 0; } c = *path++; } |