Skip to content

Commit 22973e0

Browse files
committed
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.
1 parent 0283fc4 commit 22973e0

File tree

1 file changed

+53
-0
lines changed

1 file changed

+53
-0
lines changed

src/path.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,6 +1621,59 @@ GIT_INLINE(bool) verify_dotgit_ntfs(git_repository *repo, const char *path, size
16211621
return false;
16221622
}
16231623

1624+
GIT_INLINE(bool) only_spaces_and_dots(const char *path)
1625+
{
1626+
const char *c = path;
1627+
1628+
for (;; c++) {
1629+
if (*c == '\0')
1630+
return true;
1631+
if (*c != ' ' && *c != '.')
1632+
return false;
1633+
}
1634+
1635+
return true;
1636+
}
1637+
1638+
GIT_INLINE(bool) verify_dotgit_ntfs_generic(const char *name, const char *dotgit_name, const char *shortname_pfix)
1639+
{
1640+
size_t len = strlen(name);
1641+
size_t dotgit_len = strlen(dotgit_name);
1642+
int i, saw_tilde;
1643+
1644+
if (name[0] == '.' && len >= dotgit_len &&
1645+
!strncasecmp(name + 1, dotgit_name, dotgit_len)) {
1646+
return !only_spaces_and_dots(name + dotgit_len + 1);
1647+
}
1648+
1649+
/* Detect the basic NTFS shortname with the first six chars */
1650+
if (!strncasecmp(name, dotgit_name, 6) && name[6] == '~' &&
1651+
name[7] >= '1' && name[7] <= '4')
1652+
return !only_spaces_and_dots(name + 8);
1653+
1654+
/* Catch fallback names */
1655+
for (i = 0, saw_tilde = 0; i < 8; i++) {
1656+
if (name[i] == '\0') {
1657+
return true;
1658+
} else if (saw_tilde) {
1659+
if (name[i] < '0' || name[i] > '9')
1660+
return true;
1661+
} else if (name[i] == '~') {
1662+
if (name[i+1] < '1' || name[i+1] > '9')
1663+
return true;
1664+
saw_tilde = 1;
1665+
} else if (i >= 6) {
1666+
return true;
1667+
} else if (name[i] < 0) {
1668+
return true;
1669+
} else if (git__tolower(name[i]) != shortname_pfix[i]) {
1670+
return true;
1671+
}
1672+
}
1673+
1674+
return !only_spaces_and_dots(name + i);
1675+
}
1676+
16241677
GIT_INLINE(bool) verify_char(unsigned char c, unsigned int flags)
16251678
{
16261679
if ((flags & GIT_PATH_REJECT_BACKSLASH) && c == '\\')

0 commit comments

Comments
 (0)