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>
This commit is contained in:
parent
d599e0484f
commit
daae19224a
47
fsck.c
47
fsck.c
@ -222,12 +222,47 @@ static int fsck_tree(struct tree *item, int strict, fsck_error error_func)
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int fsck_ident(char **ident, struct object *obj, fsck_error error_func)
|
||||
{
|
||||
if (**ident == '<' || **ident == '\n')
|
||||
return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
|
||||
*ident += strcspn(*ident, "<\n");
|
||||
if ((*ident)[-1] != ' ')
|
||||
return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before email");
|
||||
if (**ident != '<')
|
||||
return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing email");
|
||||
(*ident)++;
|
||||
*ident += strcspn(*ident, "<>\n");
|
||||
if (**ident != '>')
|
||||
return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad email");
|
||||
(*ident)++;
|
||||
if (**ident != ' ')
|
||||
return error_func(obj, FSCK_ERROR, "invalid author/committer line - missing space before date");
|
||||
(*ident)++;
|
||||
if (**ident == '0' && (*ident)[1] != ' ')
|
||||
return error_func(obj, FSCK_ERROR, "invalid author/committer line - zero-padded date");
|
||||
*ident += strspn(*ident, "0123456789");
|
||||
if (**ident != ' ')
|
||||
return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad date");
|
||||
(*ident)++;
|
||||
if ((**ident != '+' && **ident != '-') ||
|
||||
!isdigit((*ident)[1]) ||
|
||||
!isdigit((*ident)[2]) ||
|
||||
!isdigit((*ident)[3]) ||
|
||||
!isdigit((*ident)[4]) ||
|
||||
((*ident)[5] != '\n'))
|
||||
return error_func(obj, FSCK_ERROR, "invalid author/committer line - bad time zone");
|
||||
(*ident) += 6;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fsck_commit(struct commit *commit, fsck_error error_func)
|
||||
{
|
||||
char *buffer = commit->buffer;
|
||||
unsigned char tree_sha1[20], sha1[20];
|
||||
struct commit_graft *graft;
|
||||
int parents = 0;
|
||||
int err;
|
||||
|
||||
if (commit->date == ULONG_MAX)
|
||||
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)
|
||||
}
|
||||
if (memcmp(buffer, "author ", 7))
|
||||
return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'author' line");
|
||||
buffer += 7;
|
||||
err = fsck_ident(&buffer, &commit->object, error_func);
|
||||
if (err)
|
||||
return err;
|
||||
if (memcmp(buffer, "committer ", strlen("committer ")))
|
||||
return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'committer' line");
|
||||
buffer += strlen("committer ");
|
||||
err = fsck_ident(&buffer, &commit->object, error_func);
|
||||
if (err)
|
||||
return err;
|
||||
if (*buffer != '\n')
|
||||
return error_func(&commit->object, FSCK_ERROR, "invalid format - expected blank line");
|
||||
if (!commit->tree)
|
||||
return error_func(&commit->object, FSCK_ERROR, "could not load commit's tree %s", sha1_to_hex(tree_sha1));
|
||||
|
||||
|
@ -57,6 +57,34 @@ test_expect_success 'branch pointing to non-commit' '
|
||||
git update-ref -d refs/heads/invalid
|
||||
'
|
||||
|
||||
new=nothing
|
||||
test_expect_success 'email without @ is okay' '
|
||||
git cat-file commit HEAD >basis &&
|
||||
sed "s/@/AT/" basis >okay &&
|
||||
new=$(git hash-object -t commit -w --stdin <okay) &&
|
||||
echo "$new" &&
|
||||
git update-ref refs/heads/bogus "$new" &&
|
||||
git fsck 2>out &&
|
||||
cat out &&
|
||||
! grep "error in commit $new" out
|
||||
'
|
||||
git update-ref -d refs/heads/bogus
|
||||
rm -f ".git/objects/$new"
|
||||
|
||||
new=nothing
|
||||
test_expect_success 'email with embedded > is not okay' '
|
||||
git cat-file commit HEAD >basis &&
|
||||
sed "s/@[a-z]/&>/" basis >bad-email &&
|
||||
new=$(git hash-object -t commit -w --stdin <bad-email) &&
|
||||
echo "$new" &&
|
||||
git update-ref refs/heads/bogus "$new" &&
|
||||
git fsck 2>out &&
|
||||
cat out &&
|
||||
grep "error in commit $new" out
|
||||
'
|
||||
git update-ref -d refs/heads/bogus
|
||||
rm -f ".git/objects/$new"
|
||||
|
||||
cat > invalid-tag <<EOF
|
||||
object ffffffffffffffffffffffffffffffffffffffff
|
||||
type commit
|
||||
|
Loading…
Reference in New Issue
Block a user