Browse Source

log_tree_diff: die when we fail to parse a commit

We currently call parse_commit and then assume we can
dereference the resulting "tree" struct field. If parsing
failed, however, that field is NULL and we end up
segfaulting.

Instead of a segfault, let's print an error message and die
a little more gracefully.

Note that this should never happen in practice, but may
happen in a corrupt repository.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Jeff King 11 years ago committed by Junio C Hamano
parent
commit
7059dccc6c
  1. 7
      commit.c
  2. 1
      commit.h
  3. 6
      log-tree.c

7
commit.c

@ -341,6 +341,13 @@ int parse_commit(struct commit *item) @@ -341,6 +341,13 @@ int parse_commit(struct commit *item)
return ret;
}

void parse_commit_or_die(struct commit *item)
{
if (parse_commit(item))
die("unable to parse commit %s",
item ? sha1_to_hex(item->object.sha1) : "(null)");
}

int find_commit_subject(const char *commit_buffer, const char **subject)
{
const char *eol;

1
commit.h

@ -49,6 +49,7 @@ struct commit *lookup_commit_or_die(const unsigned char *sha1, const char *ref_n @@ -49,6 +49,7 @@ struct commit *lookup_commit_or_die(const unsigned char *sha1, const char *ref_n

int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long size);
int parse_commit(struct commit *item);
void parse_commit_or_die(struct commit *item);

/* Find beginning and length of commit subject. */
int find_commit_subject(const char *commit_buffer, const char **subject);

6
log-tree.c

@ -734,7 +734,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log @@ -734,7 +734,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
if (!opt->diff && !DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS))
return 0;

parse_commit(commit);
parse_commit_or_die(commit);
sha1 = commit->tree->object.sha1;

/* Root commit? */
@ -759,7 +759,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log @@ -759,7 +759,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
* parent, showing summary diff of the others
* we merged _in_.
*/
parse_commit(parents->item);
parse_commit_or_die(parents->item);
diff_tree_sha1(parents->item->tree->object.sha1,
sha1, "", &opt->diffopt);
log_tree_diff_flush(opt);
@ -774,7 +774,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log @@ -774,7 +774,7 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log
for (;;) {
struct commit *parent = parents->item;

parse_commit(parent);
parse_commit_or_die(parent);
diff_tree_sha1(parent->tree->object.sha1,
sha1, "", &opt->diffopt);
log_tree_diff_flush(opt);

Loading…
Cancel
Save