apply: detect and mark whitespace errors in context lines when fixing
[gitweb.git] / fsck.c
diff --git a/fsck.c b/fsck.c
index 31ce993e371c91505f98c64f49600ae4f260c2f2..5e6723d410532a6e8eec100c524d4e4c24d4a4f4 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -6,6 +6,7 @@
 #include "commit.h"
 #include "tag.h"
 #include "fsck.h"
+#include "utf8.h"
 
 static int fsck_walk_tree(struct tree *tree, fsck_walk_func walk, void *data)
 {
@@ -170,7 +171,9 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
                has_empty_name |= !*name;
                has_dot |= !strcmp(name, ".");
                has_dotdot |= !strcmp(name, "..");
-               has_dotgit |= !strcmp(name, ".git");
+               has_dotgit |= (!strcmp(name, ".git") ||
+                              is_hfs_dotgit(name) ||
+                              is_ntfs_dotgit(name));
                has_zero_pad |= *(char *)desc.buffer == '0';
                update_tree_entry(&desc);
 
@@ -237,8 +240,10 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
        return retval;
 }
 
-static int fsck_ident(char **ident, struct object *obj, fsck_error error_func)
+static int fsck_ident(const char **ident, struct object *obj, fsck_error error_func)
 {
+       char *end;
+
        if (**ident == '<')
                return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
        *ident += strcspn(*ident, "<>\n");
@@ -258,10 +263,11 @@ static int fsck_ident(char **ident, struct object *obj, fsck_error error_func)
        (*ident)++;
        if (**ident == '0' && (*ident)[1] != ' ')
                return error_func(obj, FSCK_ERROR, "invalid author/committer line - zero-padded date");
-       *ident += strspn(*ident, "0123456789");
-       if (**ident != ' ')
+       if (date_overflows(strtoul(*ident, &end, 10)))
+               return error_func(obj, FSCK_ERROR, "invalid author/committer line - date causes integer overflow");
+       if (end == *ident || *end != ' ')
                return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad date");
-       (*ident)++;
+       *ident = end + 1;
        if ((**ident != '+' && **ident != '-') ||
            !isdigit((*ident)[1]) ||
            !isdigit((*ident)[2]) ||
@@ -273,26 +279,26 @@ static int fsck_ident(char **ident, struct object *obj, fsck_error error_func)
        return 0;
 }
 
-static int fsck_commit(struct commit *commit, fsck_error error_func)
+static int fsck_commit_buffer(struct commit *commit, const char *buffer,
+                             fsck_error error_func)
 {
-       char *buffer = commit->buffer;
+       const char *tmp;
        unsigned char tree_sha1[20], sha1[20];
        struct commit_graft *graft;
        int parents = 0;
        int err;
 
-       if (commit->date == ULONG_MAX)
-               return error_func(&commit->object, FSCK_ERROR, "invalid author/committer line");
-
-       if (memcmp(buffer, "tree ", 5))
+       buffer = skip_prefix(buffer, "tree ");
+       if (!buffer)
                return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'tree' line");
-       if (get_sha1_hex(buffer+5, tree_sha1) || buffer[45] != '\n')
+       if (get_sha1_hex(buffer, tree_sha1) || buffer[40] != '\n')
                return error_func(&commit->object, FSCK_ERROR, "invalid 'tree' line format - bad sha1");
-       buffer += 46;
-       while (!memcmp(buffer, "parent ", 7)) {
-               if (get_sha1_hex(buffer+7, sha1) || buffer[47] != '\n')
+       buffer += 41;
+       while ((tmp = skip_prefix(buffer, "parent "))) {
+               buffer = tmp;
+               if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n')
                        return error_func(&commit->object, FSCK_ERROR, "invalid 'parent' line format - bad sha1");
-               buffer += 48;
+               buffer += 41;
                parents++;
        }
        graft = lookup_commit_graft(commit->object.sha1);
@@ -316,15 +322,15 @@ static int fsck_commit(struct commit *commit, fsck_error error_func)
                if (p || parents)
                        return error_func(&commit->object, FSCK_ERROR, "parent objects missing");
        }
-       if (memcmp(buffer, "author ", 7))
+       buffer = skip_prefix(buffer, "author ");
+       if (!buffer)
                return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'author' line");
-       buffer += 7;
        err = fsck_ident(&buffer, &commit->object, error_func);
        if (err)
                return err;
-       if (memcmp(buffer, "committer ", strlen("committer ")))
+       buffer = skip_prefix(buffer, "committer ");
+       if (!buffer)
                return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'committer' line");
-       buffer += strlen("committer ");
        err = fsck_ident(&buffer, &commit->object, error_func);
        if (err)
                return err;
@@ -334,6 +340,14 @@ static int fsck_commit(struct commit *commit, fsck_error error_func)
        return 0;
 }
 
+static int fsck_commit(struct commit *commit, fsck_error error_func)
+{
+       const char *buffer = get_commit_buffer(commit, NULL);
+       int ret = fsck_commit_buffer(commit, buffer, error_func);
+       unuse_commit_buffer(commit, buffer);
+       return ret;
+}
+
 static int fsck_tag(struct tag *tag, fsck_error error_func)
 {
        struct object *tagged = tag->tagged;