[PATCH 6/6] Add fsck_verify_ref_to_tag_object() to verify that refname matches name stored in tag object
From: Johan Herland <hidden>
Date: 2016-06-15 22:43:14
Subsystem:
the rest · Maintainer:
Linus Torvalds
On Monday 28 May 2007, Junio C Hamano wrote:
However it would be a good idea to add logic to fsck to warn upon inconsistencis (perhaps by mistake) between refname and tag's true name. The check would say something like: If an annotated (signed or unsigned) tag has a "tag" line to give it the official $name, and if it is pointed at by a ref, the refname must end with "/$name". Otherwise we warn. Trivially, the above rule says that having v2.6.22 tag under refs/tags/v2.6.20 is a mistake we would want to be warned upon.
This patch adds the check described by Junio. Signed-off-by: Johan Herland <redacted> --- builtin-fsck.c | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/builtin-fsck.c b/builtin-fsck.c
index a8914ae..379317e 100644
--- a/builtin-fsck.c
+++ b/builtin-fsck.c@@ -515,6 +515,25 @@ static int fsck_handle_reflog(const char *logname, const unsigned char *sha1, in return 0; } +static void fsck_verify_ref_to_tag_object(const char *refname, struct object *obj) +{ + /* Verify that refname matches the name stored in obj's "tag" header */ + struct tag *tagobj = (struct tag *) parse_object(obj->sha1); + size_t tagname_len = strlen(tagobj->tag); + size_t refname_len = strlen(refname); + + if (!tagname_len) return; /* No tag name stored in tagobj. Nothing to do. */ + + if (tagname_len < refname_len && + !memcmp(tagobj->tag, refname + (refname_len - tagname_len), tagname_len) && + refname[(refname_len - tagname_len) - 1] == '/') { + /* OK: tag name is "$name", and refname ends with "/$name" */ + return; + } + else + error("%s: Mismatch between tag ref and tag object's name %s", refname, tagobj->tag); +} + static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int flag, void *cb_data) { struct object *obj;
@@ -529,6 +548,8 @@ static int fsck_handle_ref(const char *refname, const unsigned char *sha1, int f /* We'll continue with the rest despite the error.. */ return 0; } + if (obj->type == OBJ_TAG) /* ref to tag object */ + fsck_verify_ref_to_tag_object(refname, obj); default_refs++; obj->used = 1; mark_reachable(obj, REACHABLE);
--
1.5.2