All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Shawn O. Pearce" <spearce@spearce.org>
To: Junio C Hamano <junkio@cox.net>
Cc: git@vger.kernel.org, Nicholas Miell <nmiell@gmail.com>
Subject: [PATCH] Fix infinite loop when deleting multiple packed refs.
Date: Tue, 2 Jan 2007 03:17:09 -0500	[thread overview]
Message-ID: <20070102081709.GA28779@spearce.org> (raw)
In-Reply-To: <b566b20c0701012244l21f85472k83970c0c573ce105@mail.gmail.com>

Nicholas Miell reported that `git branch -D A B` failed if both refs
A and B were packed into .git/packed-refs.  This happens because the
same pack_lock instance was being enqueued into the lock list twice,
causing the linked list to change from a singly linked list with
a NULL at the end to a circularly linked list with no termination.
This resulted in an infinite loop traversing the list during exit.

Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
---

 Nicholas Miell <nmiell@gmail.com> wrote:
 > # this is with 1.4.4.2, spearce says master is also affected.
 > # (not subscribed, please Cc:)
 > 
 > mkdir test
 > cd test
 > git init-db
 > touch blah
 > git add blah
 > git commit -m "blah"
 > git checkout -b A
 > git checkout -b B
 > git checkout master
 > git pack-refs --all --prune
 > git branch -D A B # --> infinite loop in lockfile.c:remove_lock_file()

 Fixed.  ;-)

 Junio, this applies to master, but hopefully could also apply to
 maint, as the bug also shows up there.

 refs.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/refs.c b/refs.c
index e88ed8b..f1d1a5d 100644
--- a/refs.c
+++ b/refs.c
@@ -709,10 +709,9 @@ struct ref_lock *lock_any_ref_for_update(const char *ref, const unsigned char *o
 	return lock_ref_sha1_basic(ref, old_sha1, NULL);
 }
 
-static struct lock_file packlock;
-
 static int repack_without_ref(const char *refname)
 {
+	struct lock_file *packlock;
 	struct ref_list *list, *packed_ref_list;
 	int fd;
 	int found = 0;
@@ -726,8 +725,8 @@ static int repack_without_ref(const char *refname)
 	}
 	if (!found)
 		return 0;
-	memset(&packlock, 0, sizeof(packlock));
-	fd = hold_lock_file_for_update(&packlock, git_path("packed-refs"), 0);
+	packlock = calloc(1, sizeof(*packlock));
+	fd = hold_lock_file_for_update(packlock, git_path("packed-refs"), 0);
 	if (fd < 0)
 		return error("cannot delete '%s' from packed refs", refname);
 
@@ -744,7 +743,7 @@ static int repack_without_ref(const char *refname)
 			die("too long a refname '%s'", list->name);
 		write_or_die(fd, line, len);
 	}
-	return commit_lock_file(&packlock);
+	return commit_lock_file(packlock);
 }
 
 int delete_ref(const char *refname, unsigned char *sha1)
-- 
1.5.0.rc0.gab5a

  reply	other threads:[~2007-01-02  8:17 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-01-02  6:44 infinite loop with git branch -D and packed-refs Nicholas Miell
2007-01-02  8:17 ` Shawn O. Pearce [this message]
2007-01-02  8:44   ` [PATCH] Fix infinite loop when deleting multiple packed refs Junio C Hamano
2007-01-02  8:47     ` Shawn O. Pearce
2007-01-02 19:19   ` Junio C Hamano
2007-01-05  3:04     ` Shawn O. Pearce

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=20070102081709.GA28779@spearce.org \
    --to=spearce@spearce.org \
    --cc=git@vger.kernel.org \
    --cc=junkio@cox.net \
    --cc=nmiell@gmail.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.