Merge branch 'ef/maint-win-verify-path'

* ef/maint-win-verify-path:
  verify_dotfile(): do not assume '/' is the path seperator
  verify_path(): simplify check at the directory boundary
  verify_path: consider dos drive prefix
  real_path: do not assume '/' is the path seperator
  A Windows path starting with a backslash is absolute
This commit is contained in:
Junio C Hamano
2011-06-29 17:09:17 -07:00
5 changed files with 27 additions and 17 deletions

View File

@@ -40,7 +40,7 @@ const char *real_path(const char *path)
while (depth--) { while (depth--) {
if (!is_directory(buf)) { if (!is_directory(buf)) {
char *last_slash = strrchr(buf, '/'); char *last_slash = find_last_dir_sep(buf);
if (last_slash) { if (last_slash) {
*last_slash = '\0'; *last_slash = '\0';
last_elem = xstrdup(last_slash + 1); 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) if (len + strlen(last_elem) + 2 > PATH_MAX)
die ("Too long path name: '%s/%s'", die ("Too long path name: '%s/%s'",
buf, last_elem); buf, last_elem);
if (len && buf[len-1] != '/') if (len && !is_dir_sep(buf[len-1]))
buf[len++] = '/'; buf[len++] = '/';
strcpy(buf + len, last_elem); strcpy(buf + len, last_elem);
free(last_elem); free(last_elem);

View File

@@ -747,7 +747,7 @@ extern char *expand_user_path(const char *path);
char *enter_repo(char *path, int strict); char *enter_repo(char *path, int strict);
static inline int is_absolute_path(const char *path) 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 *); int is_directory(const char *);
const char *real_path(const char *path); const char *real_path(const char *path);

View File

@@ -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 has_dos_drive_prefix(path) (isalpha(*(path)) && (path)[1] == ':')
#define is_dir_sep(c) ((c) == '/' || (c) == '\\') #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 PATH_SEP ';'
#define PRIuMAX "I64u" #define PRIuMAX "I64u"

View File

@@ -215,6 +215,10 @@ extern char *gitbasename(char *);
#define is_dir_sep(c) ((c) == '/') #define is_dir_sep(c) ((c) == '/')
#endif #endif
#ifndef find_last_dir_sep
#define find_last_dir_sep(path) strrchr(path, '/')
#endif
#if __HP_cc >= 61000 #if __HP_cc >= 61000
#define NORETURN __attribute__((noreturn)) #define NORETURN __attribute__((noreturn))
#define NORETURN_PTR #define NORETURN_PTR

View File

@@ -726,11 +726,12 @@ static int verify_dotfile(const char *rest)
* has already been discarded, we now test * has already been discarded, we now test
* the rest. * the rest.
*/ */
switch (*rest) {
/* "." is not allowed */ /* "." is not allowed */
case '\0': case '/': if (*rest == '\0' || is_dir_sep(*rest))
return 0; return 0;
switch (*rest) {
/* /*
* ".git" followed by NUL or slash is bad. This * ".git" followed by NUL or slash is bad. This
* shares the path end test with the ".." case. * shares the path end test with the ".." case.
@@ -743,7 +744,7 @@ static int verify_dotfile(const char *rest)
rest += 2; rest += 2;
/* fallthrough */ /* fallthrough */
case '.': case '.':
if (rest[1] == '\0' || rest[1] == '/') if (rest[1] == '\0' || is_dir_sep(rest[1]))
return 0; return 0;
} }
return 1; return 1;
@@ -753,23 +754,19 @@ int verify_path(const char *path)
{ {
char c; char c;
if (has_dos_drive_prefix(path))
return 0;
goto inside; goto inside;
for (;;) { for (;;) {
if (!c) if (!c)
return 1; return 1;
if (c == '/') { if (is_dir_sep(c)) {
inside: inside:
c = *path++; c = *path++;
switch (c) { if ((c == '.' && !verify_dotfile(path)) ||
default: is_dir_sep(c) || c == '\0')
continue; return 0;
case '/': case '\0':
break;
case '.':
if (verify_dotfile(path))
continue;
}
return 0;
} }
c = *path++; c = *path++;
} }