Junio C Hamano <gitster@xxxxxxxxx> writes: >> - if (memcmp(buffer, "tree ", 5)) >> + buffer = skip_prefix(buffer, "tree "); >> + if (buffer == NULL) > > We encourage people to write this as: > > if (!buffer) > > The same comment applies to other new lines in this patch. I also see a lot of repetitions in the code, before or after the patch. I wonder if a further refactoring along this line on top of these two patches might be worth considering. No, I am not proud of sneaking tree_sha1[] array pointers as a seemingly boolean-looking must-match-header parameter into the helper, but this is merely a "how about going in this direction" weather-balloon patch, so.... fsck.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 61 insertions(+), 22 deletions(-) diff --git a/fsck.c b/fsck.c index 6aab23b..a3eea7f 100644 --- a/fsck.c +++ b/fsck.c @@ -279,10 +279,55 @@ static int fsck_ident(const char **ident, struct object *obj, fsck_error error_f return 0; } +static int fsck_object_line(struct commit *commit, fsck_error error_func, + const char **buffer, const char *header, + unsigned char must_match_header[]) +{ + unsigned char sha1_buf[20]; + unsigned char *sha1 = must_match_header ? must_match_header : sha1_buf; + const char *buf; + + buf = skip_prefix(*buffer, header); + if (!buf) { + if (must_match_header) + return error_func(&commit->object, FSCK_ERROR, + "invalid format - expected '%.*s' line", + (int) strlen(header) - 1, + header); + return 1; + } + if (get_sha1_hex(buf, sha1) || buf[40] != '\n') + return error_func(&commit->object, FSCK_ERROR, + "invalid '%.*s' line format - bad sha1", + (int) strlen(header) - 1, + header); + *buffer = buf + 41; + return 0; +} + +static int fsck_ident_line(struct commit *commit, fsck_error error_func, + const char **buffer, const char *header) +{ + const char *buf; + int err; + + buf = skip_prefix(*buffer, header); + if (!buf) + return error_func(&commit->object, FSCK_ERROR, + "invalid format - expected '%.*s' line", + (int) strlen(header) - 1, + header); + err = fsck_ident(&buf, &commit->object, error_func); + if (err) + return err; + *buffer = buf; + return 0; +} + static int fsck_commit(struct commit *commit, fsck_error error_func) { - const char *buffer = commit->buffer, *tmp; - unsigned char tree_sha1[20], sha1[20]; + const char *buffer = commit->buffer; + unsigned char tree_sha1[20]; struct commit_graft *graft; int parents = 0; int err; @@ -290,18 +335,17 @@ static int fsck_commit(struct commit *commit, fsck_error error_func) if (commit->date == ULONG_MAX) return error_func(&commit->object, FSCK_ERROR, "invalid author/committer line"); - buffer = skip_prefix(buffer, "tree "); - if (!buffer) - return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'tree' line"); - if (get_sha1_hex(buffer, tree_sha1) || buffer[40] != '\n') - return error_func(&commit->object, FSCK_ERROR, "invalid 'tree' line format - bad sha1"); - buffer += 41; - while ((tmp = skip_prefix(buffer, "parent "))) { - buffer = tmp; - if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n') - return error_func(&commit->object, FSCK_ERROR, "invalid 'parent' line format - bad sha1"); - buffer += 41; - parents++; + err = fsck_object_line(commit, error_func, &buffer, "tree ", tree_sha1); + if (err) + return err; + while (1) { + err = fsck_object_line(commit, error_func, &buffer, "parent ", NULL); + if (err < 0) + return err; + else if (!err) + parents++; + else + break; } graft = lookup_commit_graft(commit->object.sha1); if (graft) { @@ -324,16 +368,11 @@ static int fsck_commit(struct commit *commit, fsck_error error_func) if (p || parents) return error_func(&commit->object, FSCK_ERROR, "parent objects missing"); } - buffer = skip_prefix(buffer, "author "); - if (!buffer) - return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'author' line"); - err = fsck_ident(&buffer, &commit->object, error_func); + + err = fsck_ident_line(commit, error_func, &buffer, "author "); if (err) return err; - buffer = skip_prefix(buffer, "committer "); - if (!buffer) - return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'committer' line"); - err = fsck_ident(&buffer, &commit->object, error_func); + err = fsck_ident_line(commit, error_func, &buffer, "committer "); if (err) return err; if (!commit->tree) -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html