From dad3f0607bf1c864f80723ab20b39527260f2c4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Thu, 5 Sep 2019 21:55:55 +0200 Subject: [PATCH 1/2] tag: factor out get_tagged_oid() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add a function for accessing the ID of the object referenced by a tag safely, i.e. without causing a segfault when encountering a broken tag where ->tagged is NULL. Signed-off-by: René Scharfe Signed-off-by: Junio C Hamano --- pack-bitmap.c | 4 +--- revision.c | 4 +--- tag.c | 7 +++++++ tag.h | 1 + 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/pack-bitmap.c b/pack-bitmap.c index ed2befaac6..30842e1e74 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -709,9 +709,7 @@ struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs) else object_list_insert(object, &wants); - if (!tag->tagged) - die("bad tag"); - object = parse_object_or_die(&tag->tagged->oid, NULL); + object = parse_object_or_die(get_tagged_oid(tag), NULL); } if (object->flags & UNINTERESTING) diff --git a/revision.c b/revision.c index 07412297f0..ee1b1552b9 100644 --- a/revision.c +++ b/revision.c @@ -404,9 +404,7 @@ static struct commit *handle_commit(struct rev_info *revs, struct tag *tag = (struct tag *) object; if (revs->tag_objects && !(flags & UNINTERESTING)) add_pending_object(revs, object, tag->tag); - if (!tag->tagged) - die("bad tag"); - object = parse_object(revs->repo, &tag->tagged->oid); + object = parse_object(revs->repo, get_tagged_oid(tag)); if (!object) { if (revs->ignore_missing_links || (flags & UNINTERESTING)) return NULL; diff --git a/tag.c b/tag.c index 5db870edb9..bfa0e31435 100644 --- a/tag.c +++ b/tag.c @@ -212,3 +212,10 @@ int parse_tag(struct tag *item) free(data); return ret; } + +struct object_id *get_tagged_oid(struct tag *tag) +{ + if (!tag->tagged) + die("bad tag"); + return &tag->tagged->oid; +} diff --git a/tag.h b/tag.h index 03265fbfe2..3ce8e72192 100644 --- a/tag.h +++ b/tag.h @@ -19,5 +19,6 @@ struct object *deref_tag(struct repository *r, struct object *, const char *, in struct object *deref_tag_noverify(struct object *); int gpg_verify_tag(const struct object_id *oid, const char *name_to_report, unsigned flags); +struct object_id *get_tagged_oid(struct tag *tag); #endif /* TAG_H */ From c77722b3ea42a87381915f1203648a5f5d86c1ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Thu, 5 Sep 2019 21:59:42 +0200 Subject: [PATCH 2/2] use get_tagged_oid() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Avoid derefencing ->tagged without checking for NULL by using the convenience wrapper for getting the ID of the tagged object. It die()s when encountering a broken tag instead of segfaulting. Signed-off-by: René Scharfe Signed-off-by: Junio C Hamano --- builtin/describe.c | 2 +- builtin/log.c | 5 +++-- builtin/replace.c | 2 +- packfile.c | 2 +- ref-filter.c | 4 ++-- 5 files changed, 8 insertions(+), 7 deletions(-) diff --git a/builtin/describe.c b/builtin/describe.c index 200154297d..e048f85484 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -313,7 +313,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) */ append_name(n, dst); if (longformat) - append_suffix(0, n->tag ? &n->tag->tagged->oid : oid, dst); + append_suffix(0, n->tag ? get_tagged_oid(n->tag) : oid, dst); if (suffix) strbuf_addstr(dst, suffix); return; diff --git a/builtin/log.c b/builtin/log.c index 44b10b3415..c4b35fdaf9 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -627,6 +627,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) break; case OBJ_TAG: { struct tag *t = (struct tag *)o; + struct object_id *oid = get_tagged_oid(t); if (rev.shown_one) putchar('\n'); @@ -638,10 +639,10 @@ int cmd_show(int argc, const char **argv, const char *prefix) rev.shown_one = 1; if (ret) break; - o = parse_object(the_repository, &t->tagged->oid); + o = parse_object(the_repository, oid); if (!o) ret = error(_("could not read object %s"), - oid_to_hex(&t->tagged->oid)); + oid_to_hex(oid)); objects[i].item = o; i--; break; diff --git a/builtin/replace.c b/builtin/replace.c index 644b21ca8d..2a4afb3b93 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -421,7 +421,7 @@ static int check_one_mergetag(struct commit *commit, if (get_oid(mergetag_data->argv[i], &oid) < 0) return error(_("not a valid object name: '%s'"), mergetag_data->argv[i]); - if (oideq(&tag->tagged->oid, &oid)) + if (oideq(get_tagged_oid(tag), &oid)) return 0; /* found */ } diff --git a/packfile.c b/packfile.c index fc43a6c52c..a62ab4cb17 100644 --- a/packfile.c +++ b/packfile.c @@ -2139,7 +2139,7 @@ static int add_promisor_object(const struct object_id *oid, oidset_insert(set, &parents->item->object.oid); } else if (obj->type == OBJ_TAG) { struct tag *tag = (struct tag *) obj; - oidset_insert(set, &tag->tagged->oid); + oidset_insert(set, get_tagged_oid(tag)); } return 0; } diff --git a/ref-filter.c b/ref-filter.c index f27cfc8c3e..8dcc17c049 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -1766,7 +1766,7 @@ static int populate_value(struct ref_array_item *ref, struct strbuf *err) * If it is a tag object, see if we use a value that derefs * the object, and if we do grab the object it refers to. */ - oi_deref.oid = ((struct tag *)obj)->tagged->oid; + oi_deref.oid = *get_tagged_oid((struct tag *)obj); /* * NEEDSWORK: This derefs tag only once, which @@ -1997,7 +1997,7 @@ static const struct object_id *match_points_at(struct oid_array *points_at, if (!obj) die(_("malformed object at '%s'"), refname); if (obj->type == OBJ_TAG) - tagged_oid = &((struct tag *)obj)->tagged->oid; + tagged_oid = get_tagged_oid((struct tag *)obj); if (tagged_oid && oid_array_lookup(points_at, tagged_oid) >= 0) return tagged_oid; return NULL;