summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar Jeff King <peff@peff.net>2018-05-02 15:23:45 -0400
committerLibravatar Jeff King <peff@peff.net>2018-05-21 23:50:11 -0400
commit0fc333ba20b43a8afee5023e92cb3384ff4e59a6 (patch)
tree6b300f5e1f0a0b3b9e0b305c96cd8cfd3033ad5b
parentis_ntfs_dotgit: use a size_t for traversing string (diff)
downloadtgif-0fc333ba20b43a8afee5023e92cb3384ff4e59a6.tar.xz
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>
-rw-r--r--utf8.c58
-rw-r--r--utf8.h5
2 files changed, 51 insertions, 12 deletions
diff --git a/utf8.c b/utf8.c
index 0c8e011a58..cbf22a71d7 100644
--- a/utf8.c
+++ b/utf8.c
@@ -619,28 +619,33 @@ static ucs_char_t next_hfs_char(const char **in)
}
}
-int is_hfs_dotgit(const char *path)
+static int is_hfs_dot_generic(const char *path,
+ const char *needle, size_t needle_len)
{
ucs_char_t c;
c = next_hfs_char(&path);
if (c != '.')
return 0;
- c = next_hfs_char(&path);
/*
* there's a great deal of other case-folding that occurs
- * in HFS+, but this is enough to catch anything that will
- * convert to ".git"
+ * in HFS+, but this is enough to catch our fairly vanilla
+ * hard-coded needles.
*/
- if (c != 'g' && c != 'G')
- return 0;
- c = next_hfs_char(&path);
- if (c != 'i' && c != 'I')
- return 0;
- c = next_hfs_char(&path);
- if (c != 't' && c != 'T')
- return 0;
+ for (; needle_len > 0; needle++, needle_len--) {
+ c = next_hfs_char(&path);
+
+ /*
+ * We know our needles contain only ASCII, so we clamp here to
+ * make the results of tolower() sane.
+ */
+ if (c > 127)
+ return 0;
+ if (tolower(c) != *needle)
+ return 0;
+ }
+
c = next_hfs_char(&path);
if (c && !is_dir_sep(c))
return 0;
@@ -648,6 +653,35 @@ int is_hfs_dotgit(const char *path)
return 1;
}
+/*
+ * Inline wrapper to make sure the compiler resolves strlen() on literals at
+ * compile time.
+ */
+static inline int is_hfs_dot_str(const char *path, const char *needle)
+{
+ return is_hfs_dot_generic(path, needle, strlen(needle));
+}
+
+int is_hfs_dotgit(const char *path)
+{
+ return is_hfs_dot_str(path, "git");
+}
+
+int is_hfs_dotgitmodules(const char *path)
+{
+ return is_hfs_dot_str(path, "gitmodules");
+}
+
+int is_hfs_dotgitignore(const char *path)
+{
+ return is_hfs_dot_str(path, "gitignore");
+}
+
+int is_hfs_dotgitattributes(const char *path)
+{
+ return is_hfs_dot_str(path, "gitattributes");
+}
+
const char utf8_bom[] = "\357\273\277";
int skip_utf8_bom(char **text, size_t len)
diff --git a/utf8.h b/utf8.h
index 6bbcf31a83..da19b43114 100644
--- a/utf8.h
+++ b/utf8.h
@@ -52,8 +52,13 @@ int mbs_chrlen(const char **text, size_t *remainder_p, const char *encoding);
* The path should be NUL-terminated, but we will match variants of both ".git\0"
* and ".git/..." (but _not_ ".../.git"). This makes it suitable for both fsck
* and verify_path().
+ *
+ * Likewise, the is_hfs_dotgitfoo() variants look for ".gitfoo".
*/
int is_hfs_dotgit(const char *path);
+int is_hfs_dotgitmodules(const char *path);
+int is_hfs_dotgitignore(const char *path);
+int is_hfs_dotgitattributes(const char *path);
typedef enum {
ALIGN_LEFT,