Skip to content

Commit 4cbf42e

Browse files
committed
Merge branch 'jn/fsck-ident'
* jn/fsck-ident: fsck: check ident lines in commit objects
2 parents 921296d + daae192 commit 4cbf42e

File tree

2 files changed

+75
-0
lines changed

2 files changed

+75
-0
lines changed

fsck.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,12 +222,47 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
222222
return retval;
223223
}
224224

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+
225259
static int fsck_commit(struct commit *commit, fsck_error error_func)
226260
{
227261
char *buffer = commit->buffer;
228262
unsigned char tree_sha1[20], sha1[20];
229263
struct commit_graft *graft;
230264
int parents = 0;
265+
int err;
231266

232267
if (commit->date == ULONG_MAX)
233268
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)
266301
}
267302
if (memcmp(buffer, "author ", 7))
268303
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");
269316
if (!commit->tree)
270317
return error_func(&commit->object, FSCK_ERROR, "could not load commit's tree %s", sha1_to_hex(tree_sha1));
271318

t/t1450-fsck.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,34 @@ test_expect_success 'branch pointing to non-commit' '
5757
git update-ref -d refs/heads/invalid
5858
'
5959

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+
6088
cat > invalid-tag <<EOF
6189
object ffffffffffffffffffffffffffffffffffffffff
6290
type commit

0 commit comments

Comments
 (0)