@matheusbsbs / matheus-bagliano / commits / daae19224a
Fork 0

fsck: check ident lines in commit objects

Check that email addresses do not contain <, >, or newline so they can be quickly scanned without trouble. The copy() function in ident.c already ensures that ordinary git commands will not write email addresses without this property. Signed-off-by: Jonathan Nieder <jrnieder@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jonathan Nieder committed Apr 24, 2010 at 11:06 UTC daae19224a05be9efb9a39c2a2c1c9a60fe906f1
2 files changed +75
fsck.c
+47
@@ -222,12 +222,47 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
222 return retval;
223 }
224
225 +static int fsck_ident(char **ident, struct object *obj, fsck_error error_func)
226 +{
227 + if (**ident == '<' || **ident == '\n')
228 + return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
229 + *ident += strcspn(*ident, "<\n");
230 + if ((*ident)[-1] != ' ')
231 + return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
232 + if (**ident != '<')
233 + return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing email");
234 + (*ident)++;
235 + *ident += strcspn(*ident, "<>\n");
236 + if (**ident != '>')
237 + return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad email");
238 + (*ident)++;
239 + if (**ident != ' ')
240 + return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before date");
241 + (*ident)++;
242 + if (**ident == '0' && (*ident)[1] != ' ')
243 + return error_func(obj, FSCK_ERROR, "invalid author/committer line - zero-padded date");
244 + *ident += strspn(*ident, "0123456789");
245 + if (**ident != ' ')
246 + return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad date");
247 + (*ident)++;
248 + if ((**ident != '+' && **ident != '-') ||
249 + !isdigit((*ident)[1]) ||
250 + !isdigit((*ident)[2]) ||
251 + !isdigit((*ident)[3]) ||
252 + !isdigit((*ident)[4]) ||
253 + ((*ident)[5] != '\n'))
254 + return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad time zone");
255 + (*ident) += 6;
256 + return 0;
257 +}
258 +
259 static int fsck_commit(struct commit *commit, fsck_error error_func)
260 {
261 char *buffer = commit->buffer;
262 unsigned char tree_sha1[20], sha1[20];
263 struct commit_graft *graft;
264 int parents = 0;
265 + int err;
266
267 if (commit->date == ULONG_MAX)
268 return error_func(&commit->object, FSCK_ERROR, "invalid author/committer line");
@@ -266,6 +301,18 @@ static int fsck_commit(struct commit *commit, fsck_error error_func)
301 }
302 if (memcmp(buffer, "author ", 7))
303 return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'author' line");
304 + buffer += 7;
305 + err = fsck_ident(&buffer, &commit->object, error_func);
306 + if (err)
307 + return err;
308 + if (memcmp(buffer, "committer ", strlen("committer ")))
309 + return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'committer' line");
310 + buffer += strlen("committer ");
311 + err = fsck_ident(&buffer, &commit->object, error_func);
312 + if (err)
313 + return err;
314 + if (*buffer != '\n')
315 + return error_func(&commit->object, FSCK_ERROR, "invalid format - expected blank line");
316 if (!commit->tree)
317 return error_func(&commit->object, FSCK_ERROR, "could not load commit's tree %s", sha1_to_hex(tree_sha1));
318
t/t1450-fsck.sh
+28
@@ -57,6 +57,34 @@ test_expect_success 'branch pointing to non-commit' '
57 git update-ref -d refs/heads/invalid
58 '
59
60 +new=nothing
61 +test_expect_success 'email without @ is okay' '
62 + git cat-file commit HEAD >basis &&
63 + sed "s/@/AT/" basis >okay &&
64 + new=$(git hash-object -t commit -w --stdin <okay) &&
65 + echo "$new" &&
66 + git update-ref refs/heads/bogus "$new" &&
67 + git fsck 2>out &&
68 + cat out &&
69 + ! grep "error in commit $new" out
70 +'
71 +git update-ref -d refs/heads/bogus
72 +rm -f ".git/objects/$new"
73 +
74 +new=nothing
75 +test_expect_success 'email with embedded > is not okay' '
76 + git cat-file commit HEAD >basis &&
77 + sed "s/@[a-z]/&>/" basis >bad-email &&
78 + new=$(git hash-object -t commit -w --stdin <bad-email) &&
79 + echo "$new" &&
80 + git update-ref refs/heads/bogus "$new" &&
81 + git fsck 2>out &&
82 + cat out &&
83 + grep "error in commit $new" out
84 +'
85 +git update-ref -d refs/heads/bogus
86 +rm -f ".git/objects/$new"
87 +
88 cat > invalid-tag <<EOF
89 object ffffffffffffffffffffffffffffffffffffffff
90 type commit