| 875 | } |
| 876 | |
| 877 | static int fsck_ident(const char **ident, const char *ident_end, |
| 878 | const struct object_id *oid, enum object_type type, |
| 879 | struct fsck_options *options) |
| 880 | { |
| 881 | const char *p = *ident; |
| 882 | const char *nl; |
| 883 | |
| 884 | nl = memchr(p, '\n', ident_end - p); |
| 885 | if (!nl) |
| 886 | BUG("verify_headers() should have made sure we have a newline"); |
| 887 | *ident = nl + 1; |
| 888 | |
| 889 | if (*p == '<') |
| 890 | return report(options, oid, type, FSCK_MSG_MISSING_NAME_BEFORE_EMAIL, "invalid author/committer line - missing space before email"); |
| 891 | for (;;) { |
| 892 | if (p >= ident_end || *p == '\n') |
| 893 | return report(options, oid, type, FSCK_MSG_MISSING_EMAIL, "invalid author/committer line - missing email"); |
| 894 | if (*p == '>') |
| 895 | return report(options, oid, type, FSCK_MSG_BAD_NAME, "invalid author/committer line - bad name"); |
| 896 | if (*p == '<') |
| 897 | break; /* end of name, beginning of email */ |
| 898 | |
| 899 | /* otherwise, skip past arbitrary name char */ |
| 900 | p++; |
| 901 | } |
| 902 | if (p[-1] != ' ') |
| 903 | return report(options, oid, type, FSCK_MSG_MISSING_SPACE_BEFORE_EMAIL, "invalid author/committer line - missing space before email"); |
| 904 | p++; /* skip past '<' we found */ |
| 905 | for (;;) { |
| 906 | if (p >= ident_end || *p == '<' || *p == '\n') |
| 907 | return report(options, oid, type, FSCK_MSG_BAD_EMAIL, "invalid author/committer line - bad email"); |
| 908 | if (*p == '>') |
| 909 | break; /* end of email */ |
| 910 | |
| 911 | /* otherwise, skip past arbitrary email char */ |
| 912 | p++; |
| 913 | } |
| 914 | p++; /* skip past '>' we found */ |
| 915 | if (*p != ' ') |
| 916 | return report(options, oid, type, FSCK_MSG_MISSING_SPACE_BEFORE_DATE, "invalid author/committer line - missing space before date"); |
| 917 | p++; |
| 918 | /* |
| 919 | * Our timestamp parser is based on the C strto*() functions, which |
| 920 | * will happily eat whitespace, including the newline that is supposed |
| 921 | * to prevent us walking past the end of the buffer. So do our own |
| 922 | * scan, skipping linear whitespace but not newlines, and then |
| 923 | * confirming we found a digit. We _could_ be even more strict here, |
| 924 | * as we really expect only a single space, but since we have |
| 925 | * traditionally allowed extra whitespace, we'll continue to do so. |
| 926 | */ |
| 927 | while (*p == ' ' || *p == '\t') |
| 928 | p++; |
| 929 | if (!isdigit(*p)) |
| 930 | return report(options, oid, type, FSCK_MSG_BAD_DATE, |
| 931 | "invalid author/committer line - bad date"); |
| 932 | if (*p == '0' && p[1] != ' ') |
| 933 | return report(options, oid, type, FSCK_MSG_ZERO_PADDED_DATE, "invalid author/committer line - zero-padded date"); |
| 934 | if (date_overflows(parse_timestamp_from_buf(&p, ident_end))) |
no test coverage detected