static int check_one_mergetag(struct commit *commit, struct commit_extra_header *extra, void *data) { struct check_mergetag_data *mergetag_data = (struct check_mergetag_data *)data; const char *ref = mergetag_data->argv[0]; struct object_id tag_oid; struct tag *tag; int i; hash_object_file(extra->value, extra->len, type_name(OBJ_TAG), &tag_oid); tag = lookup_tag(&tag_oid); if (!tag) return error(_("bad mergetag in commit '%s'"), ref); if (parse_tag_buffer(tag, extra->value, extra->len)) return error(_("malformed mergetag in commit '%s'"), ref); /* iterate over new parents */ for (i = 1; i < mergetag_data->argc; i++) { struct object_id oid; if (get_oid(mergetag_data->argv[i], &oid) < 0) return error(_("Not a valid object name: '%s'"), mergetag_data->argv[i]); if (!oidcmp(&tag->tagged->oid, &oid)) return 0; /* found */ } return error(_("original commit '%s' contains mergetag '%s' that is " "discarded; use --edit instead of --graft"), ref, oid_to_hex(&tag_oid)); }
static void show_one_mergetag(struct rev_info *opt, struct commit_extra_header *extra, struct commit *commit) { unsigned char sha1[20]; struct tag *tag; struct strbuf verify_message; int status, nth; size_t payload_size, gpg_message_offset; hash_sha1_file(extra->value, extra->len, typename(OBJ_TAG), sha1); tag = lookup_tag(sha1); if (!tag) return; /* error message already given */ strbuf_init(&verify_message, 256); if (parse_tag_buffer(tag, extra->value, extra->len)) strbuf_addstr(&verify_message, "malformed mergetag\n"); else if (is_common_merge(commit) && !hashcmp(tag->tagged->sha1, commit->parents->next->item->object.sha1)) strbuf_addf(&verify_message, "merged tag '%s'\n", tag->tag); else if ((nth = which_parent(tag->tagged->sha1, commit)) < 0) strbuf_addf(&verify_message, "tag %s names a non-parent %s\n", tag->tag, tag->tagged->sha1); else strbuf_addf(&verify_message, "parent #%d, tagged '%s'\n", nth + 1, tag->tag); gpg_message_offset = verify_message.len; payload_size = parse_signature(extra->value, extra->len); if ((extra->len <= payload_size) || (verify_signed_buffer(extra->value, payload_size, extra->value + payload_size, extra->len - payload_size, &verify_message) && verify_message.len <= gpg_message_offset)) { strbuf_addstr(&verify_message, "No signature\n"); status = -1; } else if (strstr(verify_message.buf + gpg_message_offset, ": Good signature from ")) status = 0; else status = -1; show_sig_lines(opt, status, verify_message.buf); strbuf_release(&verify_message); }
struct object *parse_object_buffer(const struct object_id *oid, enum object_type type, unsigned long size, void *buffer, int *eaten_p) { struct object *obj; *eaten_p = 0; obj = NULL; if (type == OBJ_BLOB) { struct blob *blob = lookup_blob(oid); if (blob) { if (parse_blob_buffer(blob, buffer, size)) return NULL; obj = &blob->object; } } else if (type == OBJ_TREE) { struct tree *tree = lookup_tree(oid); if (tree) { obj = &tree->object; if (!tree->buffer) tree->object.parsed = 0; if (!tree->object.parsed) { if (parse_tree_buffer(tree, buffer, size)) return NULL; *eaten_p = 1; } } } else if (type == OBJ_COMMIT) { struct commit *commit = lookup_commit(oid); if (commit) { if (parse_commit_buffer(commit, buffer, size)) return NULL; if (!get_cached_commit_buffer(commit, NULL)) { set_commit_buffer(commit, buffer, size); *eaten_p = 1; } obj = &commit->object; } } else if (type == OBJ_TAG) { struct tag *tag = lookup_tag(oid); if (tag) { if (parse_tag_buffer(tag, buffer, size)) return NULL; obj = &tag->object; } } else { warning("object %s has unknown type id %d", oid_to_hex(oid), type); obj = NULL; } return obj; }
static void show_one_mergetag(struct commit *commit, struct commit_extra_header *extra, void *data) { struct rev_info *opt = (struct rev_info *)data; unsigned char sha1[20]; struct tag *tag; struct strbuf verify_message; int status, nth; size_t payload_size, gpg_message_offset; hash_sha1_file(extra->value, extra->len, typename(OBJ_TAG), sha1); tag = lookup_tag(sha1); if (!tag) return; /* error message already given */ strbuf_init(&verify_message, 256); if (parse_tag_buffer(tag, extra->value, extra->len)) strbuf_addstr(&verify_message, "malformed mergetag\n"); else if (is_common_merge(commit) && !oidcmp(&tag->tagged->oid, &commit->parents->next->item->object.oid)) strbuf_addf(&verify_message, "merged tag '%s'\n", tag->tag); else if ((nth = which_parent(tag->tagged->oid.hash, commit)) < 0) strbuf_addf(&verify_message, "tag %s names a non-parent %s\n", tag->tag, tag->tagged->oid.hash); else strbuf_addf(&verify_message, "parent #%d, tagged '%s'\n", nth + 1, tag->tag); gpg_message_offset = verify_message.len; payload_size = parse_signature(extra->value, extra->len); status = -1; if (extra->len > payload_size) { /* could have a good signature */ if (!verify_signed_buffer(extra->value, payload_size, extra->value + payload_size, extra->len - payload_size, &verify_message, NULL)) status = 0; /* good */ else if (verify_message.len <= gpg_message_offset) strbuf_addstr(&verify_message, "No signature\n"); /* otherwise we couldn't verify, which is shown as bad */ } show_sig_lines(opt, status, verify_message.buf); strbuf_release(&verify_message); }
int parse_tag(struct tag *item) { enum object_type type; void *data; unsigned long size; int ret; if (item->object.parsed) return 0; data = read_object_file(&item->object.oid, &type, &size); if (!data) return error("Could not read %s", oid_to_hex(&item->object.oid)); if (type != OBJ_TAG) { free(data); return error("Object %s not a tag", oid_to_hex(&item->object.oid)); } ret = parse_tag_buffer(item, data, size); free(data); return ret; }