Avoid using non-portable `echo -n` in tests.
[gitweb.git] / mktag.c
diff --git a/mktag.c b/mktag.c
index 8887080a665b86ceec5b08d06a8e3c7f57281eb2..ba3d495e0715d83ffab3103e4d340a3b9ac4f4e7 100644 (file)
--- a/mktag.c
+++ b/mktag.c
@@ -45,6 +45,7 @@ static int verify_tag(char *buffer, unsigned long size)
        char type[20];
        unsigned char sha1[20];
        const char *object, *type_line, *tag_line, *tagger_line, *lb, *rb;
+       size_t len;
 
        if (size < 84)
                return error("wanna fool me ? you obviously got the size wrong !");
@@ -98,18 +99,21 @@ static int verify_tag(char *buffer, unsigned long size)
        /* Verify the tagger line */
        tagger_line = tag_line;
 
-       if (memcmp(tagger_line, "tagger ", 7) || (tagger_line[7] == '\n'))
+       if (memcmp(tagger_line, "tagger ", 7))
                return error("char" PD_FMT ": could not find \"tagger \"",
                        tagger_line - buffer);
 
        /*
         * Check for correct form for name and email
         * i.e. " <" followed by "> " on _this_ line
+        * No angle brackets within the name or email address fields.
+        * No spaces within the email address field.
         */
        tagger_line += 7;
        if (!(lb = strstr(tagger_line, " <")) || !(rb = strstr(lb+2, "> ")) ||
-               strchr(tagger_line, '\n') < rb)
-               return error("char" PD_FMT ": malformed tagger",
+               strpbrk(tagger_line, "<>\n") != lb+1 ||
+               strpbrk(lb+2, "><\n ") != rb)
+               return error("char" PD_FMT ": malformed tagger field",
                        tagger_line - buffer);
 
        /* Check for author name, at least one character, space is acceptable */
@@ -117,25 +121,20 @@ static int verify_tag(char *buffer, unsigned long size)
                return error("char" PD_FMT ": missing tagger name",
                        tagger_line - buffer);
 
-       /* timestamp */
+       /* timestamp, 1 or more digits followed by space */
        tagger_line = rb + 2;
-       if (*tagger_line == ' ')
-               return error("char" PD_FMT ": malformed tag timestamp",
+       if (!(len = strspn(tagger_line, "0123456789")))
+               return error("char" PD_FMT ": missing tag timestamp",
                        tagger_line - buffer);
-       for (;;) {
-               unsigned char c = *tagger_line++;
-               if (c == ' ')
-                       break;
-               if (isdigit(c))
-                       continue;
+       tagger_line += len;
+       if (*tagger_line != ' ')
                return error("char" PD_FMT ": malformed tag timestamp",
                        tagger_line - buffer);
-       }
+       tagger_line++;
 
        /* timezone, 5 digits [+-]hhmm, max. 1400 */
        if (!((tagger_line[0] == '+' || tagger_line[0] == '-') &&
-             isdigit(tagger_line[1]) && isdigit(tagger_line[2]) &&
-             isdigit(tagger_line[3]) && isdigit(tagger_line[4]) &&
+             strspn(tagger_line+1, "0123456789") == 4 &&
              tagger_line[5] == '\n' && atoi(tagger_line+1) <= 1400))
                return error("char" PD_FMT ": malformed tag timezone",
                        tagger_line - buffer);
@@ -154,7 +153,7 @@ static int verify_tag(char *buffer, unsigned long size)
 
 int main(int argc, char **argv)
 {
-       struct strbuf buf;
+       struct strbuf buf = STRBUF_INIT;
        unsigned char result_sha1[20];
 
        if (argc != 1)
@@ -162,7 +161,6 @@ int main(int argc, char **argv)
 
        setup_git_directory();
 
-       strbuf_init(&buf, 0);
        if (strbuf_read(&buf, 0, 4096) < 0) {
                die("could not read from stdin");
        }