diff options
author | Linus Torvalds <torvalds@osdl.org> | 2006-09-04 08:34:12 -0700 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2006-09-04 15:24:10 -0700 |
commit | 5d44cd1c8b27fb677fedc886303d38b19fbb07f7 (patch) | |
tree | c77ca9272226511f3730f168400aae621ddf7c71 /object-refs.c | |
parent | f2e609473cb4aeb3884b7dd57a3a652df4e5edcf (diff) | |
download | git-5d44cd1c8b27fb677fedc886303d38b19fbb07f7.tar.gz git-5d44cd1c8b27fb677fedc886303d38b19fbb07f7.tar.xz |
Fix git-fsck-objects SIGSEGV/divide-by-zero
If you try to fsck a repository that isn't entirely empty, but that has no
inter-object references (ie all the objects are blobs, and don't refer to
anything else), git-fsck-objects currently fails.
This probably cannot happen in practice, but can be tested with something
like
git init-db
touch dummy
git add dummy
git fsck-objects
where the fsck will die by a divide-by-zero when it tries to look up the
references from the one object it found (hash_obj() will do a modulus by
refs_hash_size).
On some other archiectures (ppc, sparc) the divide-by-zero will go
unnoticed, and we'll instead SIGSEGV when we hit the "refs_hash[j]"
access.
So move the test that should protect against this from mark_reachable()
into lookup_object_refs(), which incidentally in the process also fixes
mark_reachable() itself (it used to not mark the one object that _was_
reachable, because it decided that it had no refs too early).
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Diffstat (limited to 'object-refs.c')
-rw-r--r-- | object-refs.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/object-refs.c b/object-refs.c index b0034e4b2..98ea10005 100644 --- a/object-refs.c +++ b/object-refs.c @@ -55,9 +55,13 @@ static void add_object_refs(struct object *obj, struct object_refs *ref) struct object_refs *lookup_object_refs(struct object *obj) { - int j = hash_obj(obj, refs_hash_size); struct object_refs *ref; + int j; + /* nothing to lookup */ + if (!refs_hash_size) + return NULL; + j = hash_obj(obj, refs_hash_size); while ((ref = refs_hash[j]) != NULL) { if (ref->base == obj) break; @@ -125,9 +129,6 @@ void mark_reachable(struct object *obj, unsigned int mask) if (!track_object_refs) die("cannot do reachability with object refs turned off"); - /* nothing to lookup */ - if (!refs_hash_size) - return; /* If we've been here already, don't bother */ if (obj->flags & mask) return; |