Merge branch 'bc/gpg-verify-raw'
authorJunio C Hamano <gitster@pobox.com>
Mon, 3 Aug 2015 18:01:12 +0000 (11:01 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 3 Aug 2015 18:01:12 +0000 (11:01 -0700)
"git verify-tag" and "git verify-commit" have been taught to share
more code, and then learned to optionally show the verification
message from the underlying GPG implementation.

* bc/gpg-verify-raw:
verify-tag: add option to print raw gpg status information
verify-commit: add option to print raw gpg status information
gpg: centralize printing signature buffers
gpg: centralize signature check
verify-commit: add test for exit status on untrusted signature
verify-tag: share code with verify-commit
verify-tag: add tests

1  2 
commit.c
commit.h
diff --combined commit.c
index 6e2103cef60e8a0c2df18685280dbb5fda5c133f,909419a13b73fb9742bd7c6710586ee4fcfe525c..62223a33e5d4d05a44efca48d5ea9fbfa2e957a3
+++ b/commit.c
@@@ -55,12 -55,12 +55,12 @@@ struct commit *lookup_commit(const unsi
  
  struct commit *lookup_commit_reference_by_name(const char *name)
  {
 -      unsigned char sha1[20];
 +      struct object_id oid;
        struct commit *commit;
  
 -      if (get_sha1_committish(name, sha1))
 +      if (get_sha1_committish(name, oid.hash))
                return NULL;
 -      commit = lookup_commit_reference(sha1);
 +      commit = lookup_commit_reference(oid.hash);
        if (parse_commit(commit))
                return NULL;
        return commit;
@@@ -99,7 -99,7 +99,7 @@@ static int commit_graft_alloc, commit_g
  static const unsigned char *commit_graft_sha1_access(size_t index, void *table)
  {
        struct commit_graft **commit_graft_table = table;
 -      return commit_graft_table[index]->sha1;
 +      return commit_graft_table[index]->oid.hash;
  }
  
  static int commit_graft_pos(const unsigned char *sha1)
  
  int register_commit_graft(struct commit_graft *graft, int ignore_dups)
  {
 -      int pos = commit_graft_pos(graft->sha1);
 +      int pos = commit_graft_pos(graft->oid.hash);
  
        if (0 <= pos) {
                if (ignore_dups)
@@@ -138,23 -138,22 +138,23 @@@ struct commit_graft *read_graft_line(ch
        /* The format is just "Commit Parent1 Parent2 ...\n" */
        int i;
        struct commit_graft *graft = NULL;
 +      const int entry_size = GIT_SHA1_HEXSZ + 1;
  
        while (len && isspace(buf[len-1]))
                buf[--len] = '\0';
        if (buf[0] == '#' || buf[0] == '\0')
                return NULL;
 -      if ((len + 1) % 41)
 +      if ((len + 1) % entry_size)
                goto bad_graft_data;
 -      i = (len + 1) / 41 - 1;
 -      graft = xmalloc(sizeof(*graft) + 20 * i);
 +      i = (len + 1) / entry_size - 1;
 +      graft = xmalloc(sizeof(*graft) + GIT_SHA1_RAWSZ * i);
        graft->nr_parent = i;
 -      if (get_sha1_hex(buf, graft->sha1))
 +      if (get_oid_hex(buf, &graft->oid))
                goto bad_graft_data;
 -      for (i = 40; i < len; i += 41) {
 +      for (i = GIT_SHA1_HEXSZ; i < len; i += entry_size) {
                if (buf[i] != ' ')
                        goto bad_graft_data;
 -              if (get_sha1_hex(buf + i + 1, graft->parent[i/41]))
 +              if (get_sha1_hex(buf + i + 1, graft->parent[i/entry_size].hash))
                        goto bad_graft_data;
        }
        return graft;
@@@ -303,42 -302,39 +303,42 @@@ int parse_commit_buffer(struct commit *
  {
        const char *tail = buffer;
        const char *bufptr = buffer;
 -      unsigned char parent[20];
 +      struct object_id parent;
        struct commit_list **pptr;
        struct commit_graft *graft;
 +      const int tree_entry_len = GIT_SHA1_HEXSZ + 5;
 +      const int parent_entry_len = GIT_SHA1_HEXSZ + 7;
  
        if (item->object.parsed)
                return 0;
        item->object.parsed = 1;
        tail += size;
 -      if (tail <= bufptr + 46 || memcmp(bufptr, "tree ", 5) || bufptr[45] != '\n')
 +      if (tail <= bufptr + tree_entry_len + 1 || memcmp(bufptr, "tree ", 5) ||
 +                      bufptr[tree_entry_len] != '\n')
                return error("bogus commit object %s", sha1_to_hex(item->object.sha1));
 -      if (get_sha1_hex(bufptr + 5, parent) < 0)
 +      if (get_sha1_hex(bufptr + 5, parent.hash) < 0)
                return error("bad tree pointer in commit %s",
                             sha1_to_hex(item->object.sha1));
 -      item->tree = lookup_tree(parent);
 -      bufptr += 46; /* "tree " + "hex sha1" + "\n" */
 +      item->tree = lookup_tree(parent.hash);
 +      bufptr += tree_entry_len + 1; /* "tree " + "hex sha1" + "\n" */
        pptr = &item->parents;
  
        graft = lookup_commit_graft(item->object.sha1);
 -      while (bufptr + 48 < tail && !memcmp(bufptr, "parent ", 7)) {
 +      while (bufptr + parent_entry_len < tail && !memcmp(bufptr, "parent ", 7)) {
                struct commit *new_parent;
  
 -              if (tail <= bufptr + 48 ||
 -                  get_sha1_hex(bufptr + 7, parent) ||
 -                  bufptr[47] != '\n')
 +              if (tail <= bufptr + parent_entry_len + 1 ||
 +                  get_sha1_hex(bufptr + 7, parent.hash) ||
 +                  bufptr[parent_entry_len] != '\n')
                        return error("bad parents in commit %s", sha1_to_hex(item->object.sha1));
 -              bufptr += 48;
 +              bufptr += parent_entry_len + 1;
                /*
                 * The clone is shallow if nr_parent < 0, and we must
                 * not traverse its real parents even when we unhide them.
                 */
                if (graft && (graft->nr_parent < 0 || grafts_replace_parents))
                        continue;
 -              new_parent = lookup_commit(parent);
 +              new_parent = lookup_commit(parent.hash);
                if (new_parent)
                        pptr = &commit_list_insert(new_parent, pptr)->next;
        }
                int i;
                struct commit *new_parent;
                for (i = 0; i < graft->nr_parent; i++) {
 -                      new_parent = lookup_commit(graft->parent[i]);
 +                      new_parent = lookup_commit(graft->parent[i].hash);
                        if (!new_parent)
                                continue;
                        pptr = &commit_list_insert(new_parent, pptr)->next;
        return 0;
  }
  
 -int parse_commit(struct commit *item)
 +int parse_commit_gently(struct commit *item, int quiet_on_missing)
  {
        enum object_type type;
        void *buffer;
                return 0;
        buffer = read_sha1_file(item->object.sha1, &type, &size);
        if (!buffer)
 -              return error("Could not read %s",
 +              return quiet_on_missing ? -1 :
 +                      error("Could not read %s",
                             sha1_to_hex(item->object.sha1));
        if (type != OBJ_COMMIT) {
                free(buffer);
@@@ -1232,33 -1227,24 +1232,24 @@@ free_return
        free(buf);
  }
  
void check_commit_signature(const struct commit *commit, struct signature_check *sigc)
int check_commit_signature(const struct commit *commit, struct signature_check *sigc)
  {
        struct strbuf payload = STRBUF_INIT;
        struct strbuf signature = STRBUF_INIT;
-       struct strbuf gpg_output = STRBUF_INIT;
-       struct strbuf gpg_status = STRBUF_INIT;
-       int status;
+       int ret = 1;
  
        sigc->result = 'N';
  
        if (parse_signed_commit(commit, &payload, &signature) <= 0)
                goto out;
-       status = verify_signed_buffer(payload.buf, payload.len,
-                                     signature.buf, signature.len,
-                                     &gpg_output, &gpg_status);
-       if (status && !gpg_output.len)
-               goto out;
-       sigc->payload = strbuf_detach(&payload, NULL);
-       sigc->gpg_output = strbuf_detach(&gpg_output, NULL);
-       sigc->gpg_status = strbuf_detach(&gpg_status, NULL);
-       parse_gpg_output(sigc);
+       ret = check_signature(payload.buf, payload.len, signature.buf,
+               signature.len, sigc);
  
   out:
-       strbuf_release(&gpg_status);
-       strbuf_release(&gpg_output);
        strbuf_release(&payload);
        strbuf_release(&signature);
+       return ret;
  }
  
  
@@@ -1585,10 -1571,10 +1576,10 @@@ struct commit *get_merge_parent(const c
  {
        struct object *obj;
        struct commit *commit;
 -      unsigned char sha1[20];
 -      if (get_sha1(name, sha1))
 +      struct object_id oid;
 +      if (get_sha1(name, oid.hash))
                return NULL;
 -      obj = parse_object(sha1);
 +      obj = parse_object(oid.hash);
        commit = (struct commit *)peel_to_type(name, 0, obj, OBJ_COMMIT);
        if (commit && !commit->util) {
                struct merge_remote_desc *desc;
diff --combined commit.h
index 9a1fa961d2ba0e3ec3eae9096ef49bc7155cdd92,afa0f6f041650980e48e210cba00142068eb3ada..4983bdd3d3e3236f3df487e8e37e85756da1e360
+++ b/commit.h
@@@ -59,11 -59,7 +59,11 @@@ struct commit *lookup_commit_reference_
  struct commit *lookup_commit_or_die(const unsigned char *sha1, const char *ref_name);
  
  int parse_commit_buffer(struct commit *item, const void *buffer, unsigned long size);
 -int parse_commit(struct commit *item);
 +int parse_commit_gently(struct commit *item, int quiet_on_missing);
 +static inline int parse_commit(struct commit *item)
 +{
 +      return parse_commit_gently(item, 0);
 +}
  void parse_commit_or_die(struct commit *item);
  
  /*
@@@ -230,9 -226,9 +230,9 @@@ enum rev_sort_order 
  void sort_in_topological_order(struct commit_list **, enum rev_sort_order);
  
  struct commit_graft {
 -      unsigned char sha1[20];
 +      struct object_id oid;
        int nr_parent; /* < 0 if shallow commit */
 -      unsigned char parent[FLEX_ARRAY][20]; /* more */
 +      struct object_id parent[FLEX_ARRAY]; /* more */
  };
  typedef int (*each_commit_graft_fn)(const struct commit_graft *, void *);
  
@@@ -379,7 -375,7 +379,7 @@@ extern void print_commit_list(struct co
   * at all.  This may allocate memory for sig->gpg_output, sig->gpg_status,
   * sig->signer and sig->key.
   */
- extern void check_commit_signature(const struct commit *commit, struct signature_check *sigc);
+ extern int check_commit_signature(const struct commit *commit, struct signature_check *sigc);
  
  int compare_commits_by_commit_date(const void *a_, const void *b_, void *unused);