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"); if (memcmp(buffer, "tree ", 5)) return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'tree' line"); if (get_sha1_hex(buffer+5, tree_sha1) || buffer[45] != '\n') return error_func(&commit->object, FSCK_ERROR, "invalid 'tree' line format - bad sha1"); buffer += 46; while (!memcmp(buffer, "parent ", 7)) { if (get_sha1_hex(buffer+7, sha1) || buffer[47] != '\n') return error_func(&commit->object, FSCK_ERROR, "invalid 'parent' line format - bad sha1"); buffer += 48; parents++; } graft = lookup_commit_graft(commit->object.sha1); if (graft) { struct commit_list *p = commit->parents; parents = 0; while (p) { p = p->next; parents++; } if (graft->nr_parent == -1 && !parents) ; /* shallow commit */ else if (graft->nr_parent != parents) return error_func(&commit->object, FSCK_ERROR, "graft objects missing"); } else { struct commit_list *p = commit->parents; while (p && parents) { p = p->next; parents--; } if (p || parents) return error_func(&commit->object, FSCK_ERROR, "parent objects missing"); } 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 (!commit->tree) return error_func(&commit->object, FSCK_ERROR, "could not load commit's tree %s", sha1_to_hex(tree_sha1)); 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]; struct commit_graft *graft; int parents = 0; int err; 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++; } graft = lookup_commit_graft(commit->object.sha1); if (graft) { struct commit_list *p = commit->parents; parents = 0; while (p) { p = p->next; parents++; } if (graft->nr_parent == -1 && !parents) ; /* shallow commit */ else if (graft->nr_parent != parents) return error_func(&commit->object, FSCK_ERROR, "graft objects missing"); } else { struct commit_list *p = commit->parents; while (p && parents) { p = p->next; parents--; } 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); 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); if (err) return err; if (!commit->tree) return error_func(&commit->object, FSCK_ERROR, "could not load commit's tree %s", sha1_to_hex(tree_sha1)); return 0; }
static int fsck_commit_buffer(struct commit *commit, const char *buffer, fsck_error error_func) { unsigned char tree_sha1[20], sha1[20]; struct commit_graft *graft; unsigned parent_count, parent_line_count = 0; int err; if (!skip_prefix(buffer, "tree ", &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 (skip_prefix(buffer, "parent ", &buffer)) { if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n') return error_func(&commit->object, FSCK_ERROR, "invalid 'parent' line format - bad sha1"); buffer += 41; parent_line_count++; } graft = lookup_commit_graft(commit->object.sha1); parent_count = commit_list_count(commit->parents); if (graft) { if (graft->nr_parent == -1 && !parent_count) ; /* shallow commit */ else if (graft->nr_parent != parent_count) return error_func(&commit->object, FSCK_ERROR, "graft objects missing"); } else { if (parent_count != parent_line_count) return error_func(&commit->object, FSCK_ERROR, "parent objects missing"); } if (!skip_prefix(buffer, "author ", &buffer)) return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'author' line"); err = fsck_ident(&buffer, &commit->object, error_func); if (err) return err; if (!skip_prefix(buffer, "committer ", &buffer)) return error_func(&commit->object, FSCK_ERROR, "invalid format - expected 'committer' line"); err = fsck_ident(&buffer, &commit->object, error_func); if (err) return err; if (!commit->tree) return error_func(&commit->object, FSCK_ERROR, "could not load commit's tree %s", sha1_to_hex(tree_sha1)); return 0; }
static int fsck_commit_buffer(struct commit *commit, const char *buffer, unsigned long size, struct fsck_options *options) { unsigned char tree_sha1[20], sha1[20]; struct commit_graft *graft; unsigned parent_count, parent_line_count = 0, author_count; int err; if (verify_headers(buffer, size, &commit->object, options)) return -1; if (!skip_prefix(buffer, "tree ", &buffer)) return report(options, &commit->object, FSCK_MSG_MISSING_TREE, "invalid format - expected 'tree' line"); if (get_sha1_hex(buffer, tree_sha1) || buffer[40] != '\n') { err = report(options, &commit->object, FSCK_MSG_BAD_TREE_SHA1, "invalid 'tree' line format - bad sha1"); if (err) return err; } buffer += 41; while (skip_prefix(buffer, "parent ", &buffer)) { if (get_sha1_hex(buffer, sha1) || buffer[40] != '\n') { err = report(options, &commit->object, FSCK_MSG_BAD_PARENT_SHA1, "invalid 'parent' line format - bad sha1"); if (err) return err; } buffer += 41; parent_line_count++; } graft = lookup_commit_graft(commit->object.oid.hash); parent_count = commit_list_count(commit->parents); if (graft) { if (graft->nr_parent == -1 && !parent_count) ; /* shallow commit */ else if (graft->nr_parent != parent_count) { err = report(options, &commit->object, FSCK_MSG_MISSING_GRAFT, "graft objects missing"); if (err) return err; } } else { if (parent_count != parent_line_count) { err = report(options, &commit->object, FSCK_MSG_MISSING_PARENT, "parent objects missing"); if (err) return err; } } author_count = 0; while (skip_prefix(buffer, "author ", &buffer)) { author_count++; err = fsck_ident(&buffer, &commit->object, options); if (err) return err; } if (author_count < 1) err = report(options, &commit->object, FSCK_MSG_MISSING_AUTHOR, "invalid format - expected 'author' line"); else if (author_count > 1) err = report(options, &commit->object, FSCK_MSG_MULTIPLE_AUTHORS, "invalid format - multiple 'author' lines"); if (err) return err; if (!skip_prefix(buffer, "committer ", &buffer)) return report(options, &commit->object, FSCK_MSG_MISSING_COMMITTER, "invalid format - expected 'committer' line"); err = fsck_ident(&buffer, &commit->object, options); if (err) return err; if (!commit->tree) return report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", sha1_to_hex(tree_sha1)); return 0; }
int parse_commit_buffer(struct commit *item, void *buffer, unsigned long size) { char *bufptr = buffer; unsigned char parent[20]; struct commit_list **pptr; struct commit_graft *graft; unsigned n_refs = 0; if (item->object.parsed) return 0; item->object.parsed = 1; if (memcmp(bufptr, "tree ", 5)) return error("bogus commit object %s", sha1_to_hex(item->object.sha1)); if (get_sha1_hex(bufptr + 5, parent) < 0) return error("bad tree pointer in commit %s\n", sha1_to_hex(item->object.sha1)); item->tree = lookup_tree(parent); if (item->tree) n_refs++; bufptr += 46; /* "tree " + "hex sha1" + "\n" */ pptr = &item->parents; graft = lookup_commit_graft(item->object.sha1); while (!memcmp(bufptr, "parent ", 7)) { struct commit *new_parent; if (get_sha1_hex(bufptr + 7, parent) || bufptr[47] != '\n') return error("bad parents in commit %s", sha1_to_hex(item->object.sha1)); bufptr += 48; if (graft) continue; new_parent = lookup_commit(parent); if (new_parent) { pptr = &commit_list_insert(new_parent, pptr)->next; n_refs++; } } if (graft) { int i; struct commit *new_parent; for (i = 0; i < graft->nr_parent; i++) { new_parent = lookup_commit(graft->parent[i]); if (!new_parent) continue; pptr = &commit_list_insert(new_parent, pptr)->next; n_refs++; } } item->date = parse_commit_date(bufptr); if (track_object_refs) { unsigned i = 0; struct commit_list *p; struct object_refs *refs = alloc_object_refs(n_refs); if (item->tree) refs->ref[i++] = &item->tree->object; for (p = item->parents; p; p = p->next) refs->ref[i++] = &p->item->object; set_object_refs(&item->object, refs); } return 0; }
static int fsck_commit_buffer(struct commit *commit, const char *buffer, unsigned long size, struct fsck_options *options) { struct object_id tree_oid, oid; struct commit_graft *graft; unsigned parent_count, parent_line_count = 0, author_count; int err; const char *buffer_begin = buffer; const char *p; if (verify_headers(buffer, size, &commit->object, options)) return -1; if (!skip_prefix(buffer, "tree ", &buffer)) return report(options, &commit->object, FSCK_MSG_MISSING_TREE, "invalid format - expected 'tree' line"); if (parse_oid_hex(buffer, &tree_oid, &p) || *p != '\n') { err = report(options, &commit->object, FSCK_MSG_BAD_TREE_SHA1, "invalid 'tree' line format - bad sha1"); if (err) return err; } buffer = p + 1; while (skip_prefix(buffer, "parent ", &buffer)) { if (parse_oid_hex(buffer, &oid, &p) || *p != '\n') { err = report(options, &commit->object, FSCK_MSG_BAD_PARENT_SHA1, "invalid 'parent' line format - bad sha1"); if (err) return err; } buffer = p + 1; parent_line_count++; } graft = lookup_commit_graft(&commit->object.oid); parent_count = commit_list_count(commit->parents); if (graft) { if (graft->nr_parent == -1 && !parent_count) ; /* shallow commit */ else if (graft->nr_parent != parent_count) { err = report(options, &commit->object, FSCK_MSG_MISSING_GRAFT, "graft objects missing"); if (err) return err; } } else { if (parent_count != parent_line_count) { err = report(options, &commit->object, FSCK_MSG_MISSING_PARENT, "parent objects missing"); if (err) return err; } } author_count = 0; while (skip_prefix(buffer, "author ", &buffer)) { author_count++; err = fsck_ident(&buffer, &commit->object, options); if (err) return err; } if (author_count < 1) err = report(options, &commit->object, FSCK_MSG_MISSING_AUTHOR, "invalid format - expected 'author' line"); else if (author_count > 1) err = report(options, &commit->object, FSCK_MSG_MULTIPLE_AUTHORS, "invalid format - multiple 'author' lines"); if (err) return err; if (!skip_prefix(buffer, "committer ", &buffer)) return report(options, &commit->object, FSCK_MSG_MISSING_COMMITTER, "invalid format - expected 'committer' line"); err = fsck_ident(&buffer, &commit->object, options); if (err) return err; if (!get_commit_tree(commit)) { err = report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", oid_to_hex(&tree_oid)); if (err) return err; } if (memchr(buffer_begin, '\0', size)) { err = report(options, &commit->object, FSCK_MSG_NUL_IN_COMMIT, "NUL byte in the commit object body"); if (err) return err; } return 0; }