From: Petr Baudis <pasky@suse.cz>
To: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Cc: Junio C Hamano <junkio@cox.net>, git@vger.kernel.org
Subject: [PATCH] Warn when calling deref_tag() on broken tags
Date: Wed, 2 Nov 2005 21:41:01 +0100 [thread overview]
Message-ID: <20051102204101.GE1431@pasky.or.cz> (raw)
In-Reply-To: <Pine.LNX.4.63.0511022115250.13746@wbgn013.biozentrum.uni-wuerzburg.de>
Dear diary, on Wed, Nov 02, 2005 at 09:16:13PM CET, I got a letter
where Johannes Schindelin <Johannes.Schindelin@gmx.de> told me that...
> On Wed, 2 Nov 2005, Petr Baudis wrote:
>
> > On many places, we didn't bother checking deref_tag() return value against
> > NULL, causing GIT segfaulting e.g. on some old Cogito checkouts containing
> > residual tags from GIT.
>
> Shouldn't a warning be issued in every of those cases? I don't know, but
> those tags pointing nowhere don't seem useful to me.
Good idea. Not that I would be excited by the awing elegancy of the
patch...
---
When we hit a broken tag by deref_tag(), warn the user.
Signed-off-by: Petr Baudis <pasky@suse.cz>
---
commit.c | 2 +-
fetch-pack.c | 4 ++--
name-rev.c | 2 +-
send-pack.c | 4 ++--
server-info.c | 2 +-
sha1_name.c | 2 +-
tag.c | 12 ++++++++++--
tag.h | 2 +-
upload-pack.c | 2 +-
9 files changed, 20 insertions(+), 12 deletions(-)
diff --git a/commit.c b/commit.c
index 8f40318..78aac42 100644
--- a/commit.c
+++ b/commit.c
@@ -55,7 +55,7 @@ static struct commit *check_commit(struc
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);
if (!obj)
return NULL;
diff --git a/fetch-pack.c b/fetch-pack.c
index 1fae211..14b5918 100644
--- a/fetch-pack.c
+++ b/fetch-pack.c
@@ -38,7 +38,7 @@ static void rev_list_push(struct commit
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);
if (o && o->type == commit_type)
rev_list_push((struct commit *)o, SEEN);
@@ -317,7 +317,7 @@ static int everything_local(struct ref *
* 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), ref->name);
if (!o || o->type != commit_type || !(o->flags & COMPLETE))
continue;
diff --git a/name-rev.c b/name-rev.c
index 21fecdf..8ac2d72 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);
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 9f9a6e7..3ee6794 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -126,12 +126,12 @@ static int ref_newer(const unsigned char
/* 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);
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);
if (!o || o->type != commit_type)
return 0;
new = (struct commit *) o;
diff --git a/server-info.c b/server-info.c
index 8e13c94..23d89fb 100644
--- a/server-info.c
+++ b/server-info.c
@@ -13,7 +13,7 @@ static int add_info_ref(const char *path
fprintf(info_ref_fp, "%s %s\n", sha1_to_hex(sha1), path);
if (o->type == tag_type) {
- o = deref_tag(o);
+ o = deref_tag(o, path);
if (o)
fprintf(info_ref_fp, "%s %s^{}\n",
sha1_to_hex(o->sha1), path);
diff --git a/sha1_name.c b/sha1_name.c
index fe409fb..ae4c801 100644
--- a/sha1_name.c
+++ b/sha1_name.c
@@ -349,7 +349,7 @@ static int peel_onion(const char *name,
if (!o)
return -1;
if (!type_string) {
- o = deref_tag(o);
+ o = deref_tag(o, NULL);
if (!o || (!o->parsed && !parse_object(o->sha1)))
return -1;
memcpy(sha1, o->sha1, 20);
diff --git a/tag.c b/tag.c
index b1ab75f..9cd09cf 100644
--- a/tag.c
+++ b/tag.c
@@ -3,10 +3,18 @@
const char *tag_type = "tag";
-struct object *deref_tag(struct object *o)
+/* The refname argument is optional and suitable to use only if
+ * we use this to resolve an actual tag ref. */
+struct object *deref_tag(struct object *o, const char *refname)
{
+ struct object *o2 = o;
while (o && o->type == tag_type)
- o = parse_object(((struct tag *)o)->tagged->sha1);
+ o = parse_object(((struct tag *)(o2 = o))->tagged->sha1);
+ if (!o)
+ fprintf(stderr, "warning: invalid tag %s\n",
+ refname ? refname
+ : (o2 ? sha1_to_hex(o2->sha1)
+ : "<unknown> (this is probably internal GIT error)"));
return o;
}
diff --git a/tag.h b/tag.h
index 36e5324..2b60b45 100644
--- a/tag.h
+++ b/tag.h
@@ -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 *refname);
#endif /* TAG_H */
diff --git a/upload-pack.c b/upload-pack.c
index f0b8e63..cc5b3e3 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -226,7 +226,7 @@ static int send_ref(const char *refname,
nr_our_refs++;
}
if (o->type == tag_type) {
- o = deref_tag(o);
+ o = deref_tag(o, refname);
if (o)
packet_write(1, "%s %s^{}\n", sha1_to_hex(o->sha1), refname);
}
--
Petr "Pasky" Baudis
Stuff: http://pasky.or.cz/
VI has two modes: the one in which it beeps and the one in which
it doesn't.
next prev parent reply other threads:[~2005-11-02 20:41 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-11-02 20:07 [PATCH] Fix segfaults caused by invalid tags Petr Baudis
2005-11-02 20:16 ` Johannes Schindelin
2005-11-02 20:28 ` Junio C Hamano
2005-11-02 20:41 ` Petr Baudis [this message]
2005-11-02 20:47 ` [PATCH] Warn when calling deref_tag() on broken tags Johannes Schindelin
2005-11-02 20:50 ` Petr Baudis
2005-11-02 21:18 ` Junio C Hamano
2005-11-02 23:21 ` Junio C Hamano
2005-11-02 23:42 ` Petr Baudis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20051102204101.GE1431@pasky.or.cz \
--to=pasky@suse.cz \
--cc=Johannes.Schindelin@gmx.de \
--cc=git@vger.kernel.org \
--cc=junkio@cox.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).