summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2019-10-18 04:45:35 (GMT)
committerJunio C Hamano <gitster@pobox.com>2019-10-21 02:15:23 (GMT)
commit78d50148b955283e027ff46f310a4d3930ad42c0 (patch)
tree2f5dd3e1d4b39add0b4a82baca97f530cf3f6059
parent12736d2f027c72d4c900f10ae064d2a673344c9e (diff)
downloadgit-78d50148b955283e027ff46f310a4d3930ad42c0.zip
git-78d50148b955283e027ff46f310a4d3930ad42c0.tar.gz
git-78d50148b955283e027ff46f310a4d3930ad42c0.tar.bz2
parse_tag_buffer(): treat NULL tag pointer as parse error
When parsing a tag, we may end up with a NULL "tagged" field when there's a type mismatch (e.g., the tag claims to point to object X as a commit, but we previously saw X as a blob in the same process), but we do not otherwise indicate a parse failure to the caller. This is similar to the case discussed in the previous commit, where a commit could end up with a NULL tree field: while slightly convenient for callers who want to overlook a corrupt object, it means that normal callers have to explicitly deal with this case (rather than just relying on the return code from parsing). And most don't, leading to segfault fixes like the one in c77722b3ea (use get_tagged_oid(), 2019-09-05). Let's address this more centrally, by returning an error code from the parse itself, which most callers would already notice (adventurous callers are free to ignore the error and continue looking at the struct). This also covers the case where the tag contains a nonsensical "type" field (there we produced a user-visible error but still returned success to the caller; now we'll produce a slightly better message and return an error). Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--tag.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/tag.c b/tag.c
index bfa0e31..6a51efd 100644
--- a/tag.c
+++ b/tag.c
@@ -167,10 +167,15 @@ int parse_tag_buffer(struct repository *r, struct tag *item, const void *data, u
} else if (!strcmp(type, tag_type)) {
item->tagged = (struct object *)lookup_tag(r, &oid);
} else {
- error("Unknown type %s", type);
- item->tagged = NULL;
+ return error("unknown tag type '%s' in %s",
+ type, oid_to_hex(&item->object.oid));
}
+ if (!item->tagged)
+ return error("bad tag pointer to %s in %s",
+ oid_to_hex(&oid),
+ oid_to_hex(&item->object.oid));
+
if (bufptr + 4 < tail && starts_with(bufptr, "tag "))
; /* good */
else