don't attempt to parse Git's "leightweight" tags as real tag objects
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
diff --git a/got/got.c b/got/got.c
index 2a63d8f..263bc2c 100644
--- a/got/got.c
+++ b/got/got.c
@@ -1402,8 +1402,13 @@ print_commit(struct got_commit_object *commit, struct got_object_id *id,
name += 8;
if (strncmp(name, "tags/", 5) == 0) {
err = got_object_open_as_tag(&tag, repo, re->id);
- if (err)
- return err;
+ if (err) {
+ if (err->code != GOT_ERR_OBJ_TYPE)
+ return err;
+ /* Ref points at something other than a tag. */
+ err = NULL;
+ tag = NULL;
+ }
}
cmp = got_object_id_cmp(tag ?
got_object_tag_get_object_id(tag) : re->id, id);
diff --git a/lib/object.c b/lib/object.c
index 63fbc85..79ee0f0 100644
--- a/lib/object.c
+++ b/lib/object.c
@@ -1307,6 +1307,8 @@ open_tag(struct got_tag_object **tag, struct got_repository *repo,
struct got_packidx *packidx = NULL;
int idx;
char *path_packfile = NULL;
+ struct got_object *obj = NULL;
+ int obj_type = GOT_OBJ_TYPE_ANY;
if (check_cache) {
*tag = got_repo_get_cached_tag(repo, id);
@@ -1332,14 +1334,36 @@ open_tag(struct got_tag_object **tag, struct got_repository *repo,
if (err)
goto done;
}
- err = read_packed_tag_privsep(tag, pack,
- packidx, idx, id);
+
+ /* Beware of "leightweight" tags: Check object type first. */
+ err = read_packed_object_privsep(&obj, repo, pack, packidx,
+ idx, id);
+ if (err)
+ goto done;
+ obj_type = obj->type;
+ got_object_close(obj);
+ if (obj_type != GOT_OBJ_TYPE_TAG) {
+ err = got_error(GOT_ERR_OBJ_TYPE);
+ goto done;
+ }
+ err = read_packed_tag_privsep(tag, pack, packidx, idx, id);
} else if (err->code == GOT_ERR_NO_OBJ) {
int fd;
err = open_loose_object(&fd, id, repo);
if (err)
return err;
+ err = read_object_header_privsep(&obj, repo, fd);
+ if (err)
+ return err;
+ obj_type = obj->type;
+ got_object_close(obj);
+ if (obj_type != GOT_OBJ_TYPE_TAG)
+ return got_error(GOT_ERR_OBJ_TYPE);
+
+ err = open_loose_object(&fd, id, repo);
+ if (err)
+ return err;
err = read_tag_privsep(tag, fd, repo);
}
diff --git a/tog/tog.c b/tog/tog.c
index 68b3beb..330cb72 100644
--- a/tog/tog.c
+++ b/tog/tog.c
@@ -998,8 +998,13 @@ build_refs_str(char **refs_str, struct got_reflist_head *refs,
name += 8;
if (strncmp(name, "tags/", 5) == 0) {
err = got_object_open_as_tag(&tag, repo, re->id);
- if (err)
- break;
+ if (err) {
+ if (err->code != GOT_ERR_OBJ_TYPE)
+ break;
+ /* Ref points at something other than a tag. */
+ err = NULL;
+ tag = NULL;
+ }
}
cmp = got_object_id_cmp(tag ?
got_object_tag_get_object_id(tag) : re->id, id);