Skip to content

Commit 0fc333b

Browse files
committed
is_hfs_dotgit: match other .git files
Both verify_path() and fsck match ".git", ".GIT", and other variants specific to HFS+. Let's allow matching other special files like ".gitmodules", which we'll later use to enforce extra restrictions via verify_path() and fsck. Signed-off-by: Jeff King <[email protected]>
1 parent 11a9f4d commit 0fc333b

File tree

2 files changed

+51
-12
lines changed

2 files changed

+51
-12
lines changed

utf8.c

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -619,35 +619,69 @@ static ucs_char_t next_hfs_char(const char **in)
619619
}
620620
}
621621

622-
int is_hfs_dotgit(const char *path)
622+
static int is_hfs_dot_generic(const char *path,
623+
const char *needle, size_t needle_len)
623624
{
624625
ucs_char_t c;
625626

626627
c = next_hfs_char(&path);
627628
if (c != '.')
628629
return 0;
629-
c = next_hfs_char(&path);
630630

631631
/*
632632
* there's a great deal of other case-folding that occurs
633-
* in HFS+, but this is enough to catch anything that will
634-
* convert to ".git"
633+
* in HFS+, but this is enough to catch our fairly vanilla
634+
* hard-coded needles.
635635
*/
636-
if (c != 'g' && c != 'G')
637-
return 0;
638-
c = next_hfs_char(&path);
639-
if (c != 'i' && c != 'I')
640-
return 0;
641-
c = next_hfs_char(&path);
642-
if (c != 't' && c != 'T')
643-
return 0;
636+
for (; needle_len > 0; needle++, needle_len--) {
637+
c = next_hfs_char(&path);
638+
639+
/*
640+
* We know our needles contain only ASCII, so we clamp here to
641+
* make the results of tolower() sane.
642+
*/
643+
if (c > 127)
644+
return 0;
645+
if (tolower(c) != *needle)
646+
return 0;
647+
}
648+
644649
c = next_hfs_char(&path);
645650
if (c && !is_dir_sep(c))
646651
return 0;
647652

648653
return 1;
649654
}
650655

656+
/*
657+
* Inline wrapper to make sure the compiler resolves strlen() on literals at
658+
* compile time.
659+
*/
660+
static inline int is_hfs_dot_str(const char *path, const char *needle)
661+
{
662+
return is_hfs_dot_generic(path, needle, strlen(needle));
663+
}
664+
665+
int is_hfs_dotgit(const char *path)
666+
{
667+
return is_hfs_dot_str(path, "git");
668+
}
669+
670+
int is_hfs_dotgitmodules(const char *path)
671+
{
672+
return is_hfs_dot_str(path, "gitmodules");
673+
}
674+
675+
int is_hfs_dotgitignore(const char *path)
676+
{
677+
return is_hfs_dot_str(path, "gitignore");
678+
}
679+
680+
int is_hfs_dotgitattributes(const char *path)
681+
{
682+
return is_hfs_dot_str(path, "gitattributes");
683+
}
684+
651685
const char utf8_bom[] = "\357\273\277";
652686

653687
int skip_utf8_bom(char **text, size_t len)

utf8.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,13 @@ int mbs_chrlen(const char **text, size_t *remainder_p, const char *encoding);
5252
* The path should be NUL-terminated, but we will match variants of both ".git\0"
5353
* and ".git/..." (but _not_ ".../.git"). This makes it suitable for both fsck
5454
* and verify_path().
55+
*
56+
* Likewise, the is_hfs_dotgitfoo() variants look for ".gitfoo".
5557
*/
5658
int is_hfs_dotgit(const char *path);
59+
int is_hfs_dotgitmodules(const char *path);
60+
int is_hfs_dotgitignore(const char *path);
61+
int is_hfs_dotgitattributes(const char *path);
5762

5863
typedef enum {
5964
ALIGN_LEFT,

0 commit comments

Comments
 (0)