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 <peff@peff.net>
Jeff King committed
May 2, 2018 at 15:23 UTC
0fc333ba20b43a8afee5023e92cb3384ff4e59a6
2 files changed
+51
-12
utf8.c
+46
-12
@@ -619,28 +619,33 @@ static ucs_char_t next_hfs_char(const char **in)
619
}
620
}
621
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)
624
{
625
ucs_char_t c;
626
627
c = next_hfs_char(&path);
628
if (c != '.')
629
return 0;
629
- c = next_hfs_char(&path);
630
631
/*
632
* 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.
635
*/
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
+
649
c = next_hfs_char(&path);
650
if (c && !is_dir_sep(c))
651
return 0;
@@ -648,6 +653,35 @@ int is_hfs_dotgit(const char *path)
653
return 1;
654
}
655
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
+
685
const char utf8_bom[] = "\357\273\277";
686
687
int skip_utf8_bom(char **text, size_t len)
utf8.h
+5
@@ -52,8 +52,13 @@ int mbs_chrlen(const char **text, size_t *remainder_p, const char *encoding);
52
* The path should be NUL-terminated, but we will match variants of both ".git\0"
53
* and ".git/..." (but _not_ ".../.git"). This makes it suitable for both fsck
54
* and verify_path().
55
+ *
56
+ * Likewise, the is_hfs_dotgitfoo() variants look for ".gitfoo".
57
*/
58
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);
62
63
typedef enum {
64
ALIGN_LEFT,