diff options
author | Junio C Hamano <junkio@cox.net> | 2005-11-02 15:19:13 -0800 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2005-11-02 16:50:58 -0800 |
commit | 9534f40bc42dd826cc26c8c8c84f6a8a5fc569f6 (patch) | |
tree | 85db17a196526144838f60d848c9582c4e113d59 | |
parent | 2fd955cc0b49de9e64b2f073ce76033975f0be24 (diff) | |
download | git-9534f40bc42dd826cc26c8c8c84f6a8a5fc569f6.tar.gz git-9534f40bc42dd826cc26c8c8c84f6a8a5fc569f6.tar.xz |
Be careful when dereferencing tags.
One caller of deref_tag() was not careful enough to make sure
what deref_tag() returned was not NULL (i.e. we found a tag
object that points at an object we do not have). Fix it, and
warn about refs that point at such an incomplete tag where
needed.
Signed-off-by: Junio C Hamano <junkio@cox.net>
-rw-r--r-- | commit.c | 2 | ||||
-rw-r--r-- | fetch-pack.c | 7 | ||||
-rw-r--r-- | name-rev.c | 2 | ||||
-rw-r--r-- | send-pack.c | 4 | ||||
-rw-r--r-- | server-info.c | 7 | ||||
-rw-r--r-- | sha1_name.c | 2 | ||||
-rw-r--r-- | tag.c | 7 | ||||
-rw-r--r-- | tag.h | 2 | ||||
-rw-r--r-- | upload-pack.c | 2 |
9 files changed, 21 insertions, 14 deletions
@@ -55,7 +55,7 @@ static struct commit *check_commit(struct object *obj, struct commit *lookup_commit_reference_gently(const unsigned char *sha1, int quiet) { - struct object *obj = deref_tag(parse_object(sha1)); + struct object *obj = deref_tag(parse_object(sha1), NULL, 0); if (!obj) return NULL; diff --git a/fetch-pack.c b/fetch-pack.c index 3df991100..cb2171523 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -38,9 +38,9 @@ static void rev_list_push(struct commit *commit, int mark) static int rev_list_insert_ref(const char *path, const unsigned char *sha1) { - struct object *o = deref_tag(parse_object(sha1)); + struct object *o = deref_tag(parse_object(sha1), path, 0); - if (o->type == commit_type) + if (o && o->type == commit_type) rev_list_push((struct commit *)o, SEEN); return 0; @@ -317,7 +317,8 @@ static int everything_local(struct ref **refs, int nr_match, char **match) * Don't mark them common yet; the server has to be told so first. */ for (ref = *refs; ref; ref = ref->next) { - struct object *o = deref_tag(lookup_object(ref->old_sha1)); + struct object *o = deref_tag(lookup_object(ref->old_sha1), + NULL, 0); if (!o || o->type != commit_type || !(o->flags & COMPLETE)) continue; diff --git a/name-rev.c b/name-rev.c index 21fecdf54..59194f134 100644 --- a/name-rev.c +++ b/name-rev.c @@ -164,7 +164,7 @@ int main(int argc, char **argv) continue; } - o = deref_tag(parse_object(sha1)); + o = deref_tag(parse_object(sha1), *argv, 0); if (!o || o->type != commit_type) { fprintf(stderr, "Could not get commit for %s. Skipping.\n", *argv); diff --git a/send-pack.c b/send-pack.c index 9f9a6e70b..3eeb18f7c 100644 --- a/send-pack.c +++ b/send-pack.c @@ -126,12 +126,12 @@ static int ref_newer(const unsigned char *new_sha1, /* Both new and old must be commit-ish and new is descendant of * old. Otherwise we require --force. */ - o = deref_tag(parse_object(old_sha1)); + o = deref_tag(parse_object(old_sha1), NULL, 0); if (!o || o->type != commit_type) return 0; old = (struct commit *) o; - o = deref_tag(parse_object(new_sha1)); + o = deref_tag(parse_object(new_sha1), NULL, 0); if (!o || o->type != commit_type) return 0; new = (struct commit *) o; diff --git a/server-info.c b/server-info.c index ba5359108..0cba8e19f 100644 --- a/server-info.c +++ b/server-info.c @@ -13,9 +13,10 @@ static int add_info_ref(const char *path, const unsigned char *sha1) fprintf(info_ref_fp, "%s %s\n", sha1_to_hex(sha1), path); if (o->type == tag_type) { - o = deref_tag(o); - fprintf(info_ref_fp, "%s %s^{}\n", - sha1_to_hex(o->sha1), path); + o = deref_tag(o, path, 0); + if (o) + fprintf(info_ref_fp, "%s %s^{}\n", + sha1_to_hex(o->sha1), path); } return 0; } diff --git a/sha1_name.c b/sha1_name.c index fe409fbce..be1755a70 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -349,7 +349,7 @@ static int peel_onion(const char *name, int len, unsigned char *sha1) if (!o) return -1; if (!type_string) { - o = deref_tag(o); + o = deref_tag(o, name, sp - name - 2); if (!o || (!o->parsed && !parse_object(o->sha1))) return -1; memcpy(sha1, o->sha1, 20); @@ -3,10 +3,15 @@ const char *tag_type = "tag"; -struct object *deref_tag(struct object *o) +struct object *deref_tag(struct object *o, const char *warn, int warnlen) { while (o && o->type == tag_type) o = parse_object(((struct tag *)o)->tagged->sha1); + if (!o && warn) { + if (!warnlen) + warnlen = strlen(warn); + error("missing object referenced by '%.*s'", warnlen, warn); + } return o; } @@ -15,6 +15,6 @@ struct tag { extern struct tag *lookup_tag(const unsigned char *sha1); extern int parse_tag_buffer(struct tag *item, void *data, unsigned long size); extern int parse_tag(struct tag *item); -extern struct object *deref_tag(struct object *); +extern struct object *deref_tag(struct object *, const char *, int); #endif /* TAG_H */ diff --git a/upload-pack.c b/upload-pack.c index c5eff2136..be6313280 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -226,7 +226,7 @@ static int send_ref(const char *refname, const unsigned char *sha1) nr_our_refs++; } if (o->type == tag_type) { - o = deref_tag(o); + o = deref_tag(o, refname, 0); packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname); } return 0; |