{"thread":{"id":"13449","subject":"[PATCH 1/2] ident.c: New function valid_ident for checking ident string formatting","startedAt":"2008-05-09T05:03:35Z","lastAt":"2008-05-09T05:03:35Z","messageCount":1,"participants":["drafnel@gmail.com"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"76442","messageId":"56662.1210309343088.JavaMail.teamon@b304.teamon.com","threadId":"13449","inReplyTo":null,"subject":"[PATCH 1/2] ident.c: New function valid_ident for checking ident string formatting","fromName":"","fromEmail":"drafnel@gmail.com","sentAt":"2008-05-09T05:03:35Z","receivedAt":"2008-05-09T05:03:35Z","isPatch":true,"sender":{"key":"drafnel@gmail.com","avatar":"https://avatars.githubusercontent.com/u/921167?v=4"},"body":"From: Brandon Casey <drafnel@gmail.com>\n\nThis function provides a centralized method for checking ident\nstrings which can be shared by the functions creating or parsing\nauthor, committer, or tagger fields.\n\nSigned-off-by: Brandon Casey <drafnel@gmail.com>\n---\n cache.h |    1 +\n ident.c |   69 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n 2 files changed, 70 insertions(+), 0 deletions(-)\n\ndiff --git a/cache.h b/cache.h\nindex d5d5dad..92f21e1 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -580,6 +580,7 @@ extern const char *git_author_info(int);\n extern const char *git_committer_info(int);\n extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int);\n extern const char *fmt_name(const char *name, const char *email);\n+extern int valid_ident(const char *buf, size_t size, int flag);\n \n struct checkout {\n \tconst char *base_dir;\ndiff --git a/ident.c b/ident.c\nindex ed44a53..1dc9b22 100644\n--- a/ident.c\n+++ b/ident.c\n@@ -167,6 +167,75 @@ static int copy(char *buf, size_t size, int offset, const char *src)\n \treturn offset;\n }\n \n+int valid_ident(const char *buf, size_t size, int flag)\n+{\n+        const char *s, *lb, *rb;\n+\tint name_addr_only = (flag & IDENT_NO_DATE);\n+\n+        /* check for leading crud */\n+\tif (crud(*buf))\n+\t\treturn 0;\n+\n+\t/* Find start of email and check for disallowed chars in name */\n+\tif (!(lb = strstr(buf, \" <\")) || strpbrk(buf, \"<>\\n\") < lb)\n+\t\treturn 0;\n+\n+\t/* Check for empty name and trailing crud in name */\n+\tif (lb == buf || crud(lb[-1]))\n+\t\treturn 0;\n+\n+\t/* Find end of email and check for disallowed chars in email */\n+\tif (!(rb = strchr(lb+2, '>')) || strpbrk(lb+2, \"><\\n \") < rb)\n+\t\treturn 0;\n+\n+\t/* Check for leading or trailing crud in email */\n+\tif (rb > lb+2 && (crud(lb[2]) || crud(rb[-1])))\n+\t\treturn 0;\n+\n+\ts = rb+1;\n+\tif (!name_addr_only) {\n+\t\tchar tz[5];\n+\t\tsize_t len;\n+\n+\t\t/* a space separates email from timestamp */\n+\t\tif (*s != ' ')\n+\t\t\treturn 0;\n+\t\ts++;\n+\n+\t\t/*\n+\t\t * timestamp, 1 or more digits followed by space.\n+\t\t * fast-import at least assumes the timestamp and\n+\t\t * timezone fields will be 23 bytes or less. That\n+\t\t * leaves 17 bytes for the timestamp.\n+\t\t */\n+\t\tif (!(len = strspn(s, \"0123456789\")) || len > 17)\n+\t\t\treturn 0;\n+\t\ts += len;\n+\n+\t\t/* a space separates timestamp from timezone */\n+\t\tif (*s != ' ')\n+\t\t\treturn 0;\n+\t\ts++;\n+\n+\t\t/*\n+                 * timezone, 5 digits [+-]hhmm, max. 1400\n+                 * A buffer is used here to hold the timezone characters\n+                 * since our string may not be nul terminated immediately\n+                 * after the timezone field. Though it must adhere to the\n+                 * size parameter supplied by the caller.\n+                 */\n+\t\tif (!((s[0] == '+' || s[0] == '-') &&\n+\t\t      strlcpy(tz, s+1, 5) >= 4 &&\n+\t\t      strspn(tz, \"0123456789\") == 4 &&\n+\t\t      atoi(tz) <= 1400))\n+\t\t\treturn 0;\n+\n+\t\ts += 5;\n+\t}\n+\n+\treturn (s - buf == size);\n+}\n+\n static const char au_env[] = \"GIT_AUTHOR_NAME\";\n static const char co_env[] = \"GIT_COMMITTER_NAME\";\n static const char *env_hint =\n-- \n1.5.5.67.g9a49\n"}]}