tag.con commit tag: don't warn if target is missing but promised (8c4cc32)
   1#include "cache.h"
   2#include "tag.h"
   3#include "commit.h"
   4#include "tree.h"
   5#include "blob.h"
   6#include "gpg-interface.h"
   7#include "packfile.h"
   8
   9const char *tag_type = "tag";
  10
  11static int run_gpg_verify(const char *buf, unsigned long size, unsigned flags)
  12{
  13        struct signature_check sigc;
  14        size_t payload_size;
  15        int ret;
  16
  17        memset(&sigc, 0, sizeof(sigc));
  18
  19        payload_size = parse_signature(buf, size);
  20
  21        if (size == payload_size) {
  22                if (flags & GPG_VERIFY_VERBOSE)
  23                        write_in_full(1, buf, payload_size);
  24                return error("no signature found");
  25        }
  26
  27        ret = check_signature(buf, payload_size, buf + payload_size,
  28                                size - payload_size, &sigc);
  29
  30        if (!(flags & GPG_VERIFY_OMIT_STATUS))
  31                print_signature_buffer(&sigc, flags);
  32
  33        signature_check_clear(&sigc);
  34        return ret;
  35}
  36
  37int gpg_verify_tag(const struct object_id *oid, const char *name_to_report,
  38                unsigned flags)
  39{
  40        enum object_type type;
  41        char *buf;
  42        unsigned long size;
  43        int ret;
  44
  45        type = oid_object_info(the_repository, oid, NULL);
  46        if (type != OBJ_TAG)
  47                return error("%s: cannot verify a non-tag object of type %s.",
  48                                name_to_report ?
  49                                name_to_report :
  50                                find_unique_abbrev(oid, DEFAULT_ABBREV),
  51                                type_name(type));
  52
  53        buf = read_object_file(oid, &type, &size);
  54        if (!buf)
  55                return error("%s: unable to read file.",
  56                                name_to_report ?
  57                                name_to_report :
  58                                find_unique_abbrev(oid, DEFAULT_ABBREV));
  59
  60        ret = run_gpg_verify(buf, size, flags);
  61
  62        free(buf);
  63        return ret;
  64}
  65
  66struct object *deref_tag(struct object *o, const char *warn, int warnlen)
  67{
  68        struct object_id *last_oid = NULL;
  69        while (o && o->type == OBJ_TAG)
  70                if (((struct tag *)o)->tagged) {
  71                        last_oid = &((struct tag *)o)->tagged->oid;
  72                        o = parse_object(last_oid);
  73                } else {
  74                        last_oid = NULL;
  75                        o = NULL;
  76                }
  77        if (!o && warn) {
  78                if (last_oid && is_promisor_object(last_oid))
  79                        return NULL;
  80                if (!warnlen)
  81                        warnlen = strlen(warn);
  82                error("missing object referenced by '%.*s'", warnlen, warn);
  83        }
  84        return o;
  85}
  86
  87struct object *deref_tag_noverify(struct object *o)
  88{
  89        while (o && o->type == OBJ_TAG) {
  90                o = parse_object(&o->oid);
  91                if (o && o->type == OBJ_TAG && ((struct tag *)o)->tagged)
  92                        o = ((struct tag *)o)->tagged;
  93                else
  94                        o = NULL;
  95        }
  96        return o;
  97}
  98
  99struct tag *lookup_tag(const struct object_id *oid)
 100{
 101        struct object *obj = lookup_object(oid->hash);
 102        if (!obj)
 103                return create_object(oid->hash, alloc_tag_node());
 104        return object_as_type(obj, OBJ_TAG, 0);
 105}
 106
 107static timestamp_t parse_tag_date(const char *buf, const char *tail)
 108{
 109        const char *dateptr;
 110
 111        while (buf < tail && *buf++ != '>')
 112                /* nada */;
 113        if (buf >= tail)
 114                return 0;
 115        dateptr = buf;
 116        while (buf < tail && *buf++ != '\n')
 117                /* nada */;
 118        if (buf >= tail)
 119                return 0;
 120        /* dateptr < buf && buf[-1] == '\n', so parsing will stop at buf-1 */
 121        return parse_timestamp(dateptr, NULL, 10);
 122}
 123
 124int parse_tag_buffer(struct tag *item, const void *data, unsigned long size)
 125{
 126        struct object_id oid;
 127        char type[20];
 128        const char *bufptr = data;
 129        const char *tail = bufptr + size;
 130        const char *nl;
 131
 132        if (item->object.parsed)
 133                return 0;
 134        item->object.parsed = 1;
 135
 136        if (size < GIT_SHA1_HEXSZ + 24)
 137                return -1;
 138        if (memcmp("object ", bufptr, 7) || parse_oid_hex(bufptr + 7, &oid, &bufptr) || *bufptr++ != '\n')
 139                return -1;
 140
 141        if (!starts_with(bufptr, "type "))
 142                return -1;
 143        bufptr += 5;
 144        nl = memchr(bufptr, '\n', tail - bufptr);
 145        if (!nl || sizeof(type) <= (nl - bufptr))
 146                return -1;
 147        memcpy(type, bufptr, nl - bufptr);
 148        type[nl - bufptr] = '\0';
 149        bufptr = nl + 1;
 150
 151        if (!strcmp(type, blob_type)) {
 152                item->tagged = (struct object *)lookup_blob(&oid);
 153        } else if (!strcmp(type, tree_type)) {
 154                item->tagged = (struct object *)lookup_tree(&oid);
 155        } else if (!strcmp(type, commit_type)) {
 156                item->tagged = (struct object *)lookup_commit(&oid);
 157        } else if (!strcmp(type, tag_type)) {
 158                item->tagged = (struct object *)lookup_tag(&oid);
 159        } else {
 160                error("Unknown type %s", type);
 161                item->tagged = NULL;
 162        }
 163
 164        if (bufptr + 4 < tail && starts_with(bufptr, "tag "))
 165                ;               /* good */
 166        else
 167                return -1;
 168        bufptr += 4;
 169        nl = memchr(bufptr, '\n', tail - bufptr);
 170        if (!nl)
 171                return -1;
 172        item->tag = xmemdupz(bufptr, nl - bufptr);
 173        bufptr = nl + 1;
 174
 175        if (bufptr + 7 < tail && starts_with(bufptr, "tagger "))
 176                item->date = parse_tag_date(bufptr, tail);
 177        else
 178                item->date = 0;
 179
 180        return 0;
 181}
 182
 183int parse_tag(struct tag *item)
 184{
 185        enum object_type type;
 186        void *data;
 187        unsigned long size;
 188        int ret;
 189
 190        if (item->object.parsed)
 191                return 0;
 192        data = read_object_file(&item->object.oid, &type, &size);
 193        if (!data)
 194                return error("Could not read %s",
 195                             oid_to_hex(&item->object.oid));
 196        if (type != OBJ_TAG) {
 197                free(data);
 198                return error("Object %s not a tag",
 199                             oid_to_hex(&item->object.oid));
 200        }
 201        ret = parse_tag_buffer(item, data, size);
 202        free(data);
 203        return ret;
 204}