Merge branch 'maint'
authorJunio C Hamano <junkio@cox.net>
Fri, 5 Jan 2007 06:28:21 +0000 (22:28 -0800)
committerJunio C Hamano <junkio@cox.net>
Fri, 5 Jan 2007 06:28:21 +0000 (22:28 -0800)
* maint:
pack-check.c::verify_packfile(): don't run SHA-1 update on huge data
Fix infinite loop when deleting multiple packed refs.

cache.h
lockfile.c
pack-check.c
refs.c
diff --git a/cache.h b/cache.h
index 384f829b96a5056d843548c39c4e55976a9a7772..31b0819e83d7f76ed52db7771cf274e74b2156dc 100644 (file)
--- a/cache.h
+++ b/cache.h
@@ -179,6 +179,7 @@ extern int refresh_cache(unsigned int flags);
 
 struct lock_file {
        struct lock_file *next;
+       char on_list;
        char filename[PATH_MAX];
 };
 extern int hold_lock_file_for_update(struct lock_file *, const char *path, int);
index 261baff049cd8b2e4d1b1a269992851eb00b2aa8..731bbf3c9c312687714d19391e6e02ffde8eaebd 100644 (file)
@@ -27,9 +27,12 @@ static int lock_file(struct lock_file *lk, const char *path)
        sprintf(lk->filename, "%s.lock", path);
        fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
        if (0 <= fd) {
-               if (!lk->next) {
+               if (!lk->on_list) {
                        lk->next = lock_file_list;
                        lock_file_list = lk;
+                       lk->on_list = 1;
+               }
+               if (lock_file_list) {
                        signal(SIGINT, remove_lock_file_on_signal);
                        atexit(remove_lock_file);
                }
@@ -37,6 +40,8 @@ static int lock_file(struct lock_file *lk, const char *path)
                        return error("cannot fix permission bits on %s",
                                     lk->filename);
        }
+       else
+               lk->filename[0] = 0;
        return fd;
 }
 
index c0caaee0933382f30cc932731e1e387cc9a03c12..8e123b71ed7898d2054ed9ef729c70ed40422bc3 100644 (file)
@@ -1,16 +1,18 @@
 #include "cache.h"
 #include "pack.h"
 
+#define BATCH (1u<<20)
+
 static int verify_packfile(struct packed_git *p)
 {
        unsigned long index_size = p->index_size;
        void *index_base = p->index_base;
        SHA_CTX ctx;
        unsigned char sha1[20];
-       unsigned long pack_size = p->pack_size;
-       void *pack_base;
        struct pack_header *hdr;
        int nr_objects, err, i;
+       unsigned char *packdata;
+       unsigned long datasize;
 
        /* Header consistency check */
        hdr = p->pack_base;
@@ -25,11 +27,19 @@ static int verify_packfile(struct packed_git *p)
                             "while idx size expects %d", nr_objects,
                             num_packed_objects(p));
 
+       /* Check integrity of pack data with its SHA-1 checksum */
        SHA1_Init(&ctx);
-       pack_base = p->pack_base;
-       SHA1_Update(&ctx, pack_base, pack_size - 20);
+       packdata = p->pack_base;
+       datasize = p->pack_size - 20;
+       while (datasize) {
+               unsigned long batch = (datasize < BATCH) ? datasize : BATCH;
+               SHA1_Update(&ctx, packdata, batch);
+               datasize -= batch;
+               packdata += batch;
+       }
        SHA1_Final(sha1, &ctx);
-       if (hashcmp(sha1, (unsigned char *)pack_base + pack_size - 20))
+
+       if (hashcmp(sha1, (unsigned char *)(p->pack_base) + p->pack_size - 20))
                return error("Packfile %s SHA1 mismatch with itself",
                             p->pack_name);
        if (hashcmp(sha1, (unsigned char *)index_base + index_size - 40))
diff --git a/refs.c b/refs.c
index e88ed8b2d3f42f48e6859de16f3d6a7f3641a84c..f76b4fe20dea81f99b330103ce9d05cc6364c96c 100644 (file)
--- a/refs.c
+++ b/refs.c
@@ -726,7 +726,6 @@ 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);
        if (fd < 0)
                return error("cannot delete '%s' from packed refs", refname);