Merge branch 'maint'

* maint:
  pack-check.c::verify_packfile(): don't run SHA-1 update on huge data
  Fix infinite loop when deleting multiple packed refs.
maint
Junio C Hamano 2007-01-04 22:28:21 -08:00
commit e27e609bbf
4 changed files with 22 additions and 7 deletions

View File

@ -179,6 +179,7 @@ extern int refresh_cache(unsigned int flags);


struct lock_file { struct lock_file {
struct lock_file *next; struct lock_file *next;
char on_list;
char filename[PATH_MAX]; char filename[PATH_MAX];
}; };
extern int hold_lock_file_for_update(struct lock_file *, const char *path, int); extern int hold_lock_file_for_update(struct lock_file *, const char *path, int);

View File

@ -27,9 +27,12 @@ static int lock_file(struct lock_file *lk, const char *path)
sprintf(lk->filename, "%s.lock", path); sprintf(lk->filename, "%s.lock", path);
fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666); fd = open(lk->filename, O_RDWR | O_CREAT | O_EXCL, 0666);
if (0 <= fd) { if (0 <= fd) {
if (!lk->next) { if (!lk->on_list) {
lk->next = lock_file_list; lk->next = lock_file_list;
lock_file_list = lk; lock_file_list = lk;
lk->on_list = 1;
}
if (lock_file_list) {
signal(SIGINT, remove_lock_file_on_signal); signal(SIGINT, remove_lock_file_on_signal);
atexit(remove_lock_file); 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", return error("cannot fix permission bits on %s",
lk->filename); lk->filename);
} }
else
lk->filename[0] = 0;
return fd; return fd;
} }



View File

@ -1,16 +1,18 @@
#include "cache.h" #include "cache.h"
#include "pack.h" #include "pack.h"


#define BATCH (1u<<20)

static int verify_packfile(struct packed_git *p) static int verify_packfile(struct packed_git *p)
{ {
unsigned long index_size = p->index_size; unsigned long index_size = p->index_size;
void *index_base = p->index_base; void *index_base = p->index_base;
SHA_CTX ctx; SHA_CTX ctx;
unsigned char sha1[20]; unsigned char sha1[20];
unsigned long pack_size = p->pack_size;
void *pack_base;
struct pack_header *hdr; struct pack_header *hdr;
int nr_objects, err, i; int nr_objects, err, i;
unsigned char *packdata;
unsigned long datasize;


/* Header consistency check */ /* Header consistency check */
hdr = p->pack_base; hdr = p->pack_base;
@ -25,11 +27,19 @@ static int verify_packfile(struct packed_git *p)
"while idx size expects %d", nr_objects, "while idx size expects %d", nr_objects,
num_packed_objects(p)); num_packed_objects(p));


/* Check integrity of pack data with its SHA-1 checksum */
SHA1_Init(&ctx); SHA1_Init(&ctx);
pack_base = p->pack_base; packdata = p->pack_base;
SHA1_Update(&ctx, pack_base, pack_size - 20); 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); 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", return error("Packfile %s SHA1 mismatch with itself",
p->pack_name); p->pack_name);
if (hashcmp(sha1, (unsigned char *)index_base + index_size - 40)) if (hashcmp(sha1, (unsigned char *)index_base + index_size - 40))

1
refs.c
View File

@ -726,7 +726,6 @@ static int repack_without_ref(const char *refname)
} }
if (!found) if (!found)
return 0; return 0;
memset(&packlock, 0, sizeof(packlock));
fd = hold_lock_file_for_update(&packlock, git_path("packed-refs"), 0); fd = hold_lock_file_for_update(&packlock, git_path("packed-refs"), 0);
if (fd < 0) if (fd < 0)
return error("cannot delete '%s' from packed refs", refname); return error("cannot delete '%s' from packed refs", refname);