Commit 3908c254 by Carlos Martín Nieto Committed by Carlos Martín Nieto

indexer: correctly deal with objects larger than the window size

A mmap-window is not guaranteed to give you the whole object, but the
indexer currently assumes so.

Loop asking for more data until we've successfully CRC'd all of the
packed data.
parent 5a3ad89d
...@@ -261,18 +261,38 @@ static int read_object_stream(git_packfile_stream *stream) ...@@ -261,18 +261,38 @@ static int read_object_stream(git_packfile_stream *stream)
return 0; return 0;
} }
static int crc_object(uint32_t *crc_out, git_mwindow_file *mwf, git_off_t start, git_off_t size)
{
void *ptr;
uint32_t crc;
unsigned int left, len;
git_mwindow *w = NULL;
crc = crc32(0L, Z_NULL, 0);
while (size) {
ptr = git_mwindow_open(mwf, &w, start, size, &left);
if (ptr == NULL)
return -1;
len = min(left, size);
crc = crc32(crc, ptr, len);
size -= len;
start += len;
git_mwindow_close(&w);
}
*crc_out = htonl(crc);
return 0;
}
static int store_object(git_indexer_stream *idx) static int store_object(git_indexer_stream *idx)
{ {
int i; int i;
git_oid oid; git_oid oid;
void *packed;
unsigned int left;
struct entry *entry; struct entry *entry;
git_off_t entry_size; git_off_t entry_size;
git_mwindow *w = NULL;
struct git_pack_entry *pentry; struct git_pack_entry *pentry;
git_hash_ctx *ctx = &idx->hash_ctx; git_hash_ctx *ctx = &idx->hash_ctx;
git_mwindow_file *mwf = &idx->pack->mwf;
git_off_t entry_start = idx->entry_start; git_off_t entry_start = idx->entry_start;
entry = git__calloc(1, sizeof(*entry)); entry = git__calloc(1, sizeof(*entry));
...@@ -298,15 +318,10 @@ static int store_object(git_indexer_stream *idx) ...@@ -298,15 +318,10 @@ static int store_object(git_indexer_stream *idx)
} }
git_oid_cpy(&entry->oid, &oid); git_oid_cpy(&entry->oid, &oid);
entry->crc = crc32(0L, Z_NULL, 0);
packed = git_mwindow_open(mwf, &w, entry_start, entry_size, &left); if (crc_object(&entry->crc, &idx->pack->mwf, entry_start, entry_size) < 0)
if (packed == NULL)
goto on_error; goto on_error;
entry->crc = htonl(crc32(entry->crc, packed, (uInt)entry_size));
git_mwindow_close(&w);
/* Add the object to the list */ /* Add the object to the list */
if (git_vector_insert(&idx->objects, entry) < 0) if (git_vector_insert(&idx->objects, entry) < 0)
goto on_error; goto on_error;
...@@ -327,12 +342,8 @@ static int hash_and_save(git_indexer_stream *idx, git_rawobj *obj, git_off_t ent ...@@ -327,12 +342,8 @@ static int hash_and_save(git_indexer_stream *idx, git_rawobj *obj, git_off_t ent
{ {
int i; int i;
git_oid oid; git_oid oid;
void *packed;
size_t entry_size; size_t entry_size;
unsigned int left;
struct entry *entry; struct entry *entry;
git_mwindow *w = NULL;
git_mwindow_file *mwf = &idx->pack->mwf;
struct git_pack_entry *pentry; struct git_pack_entry *pentry;
entry = git__calloc(1, sizeof(*entry)); entry = git__calloc(1, sizeof(*entry));
...@@ -365,13 +376,9 @@ static int hash_and_save(git_indexer_stream *idx, git_rawobj *obj, git_off_t ent ...@@ -365,13 +376,9 @@ static int hash_and_save(git_indexer_stream *idx, git_rawobj *obj, git_off_t ent
entry->crc = crc32(0L, Z_NULL, 0); entry->crc = crc32(0L, Z_NULL, 0);
entry_size = (size_t)(idx->off - entry_start); entry_size = (size_t)(idx->off - entry_start);
packed = git_mwindow_open(mwf, &w, entry_start, entry_size, &left); if (crc_object(&entry->crc, &idx->pack->mwf, entry_start, entry_size) < 0)
if (packed == NULL)
goto on_error; goto on_error;
entry->crc = htonl(crc32(entry->crc, packed, (uInt)entry_size));
git_mwindow_close(&w);
/* Add the object to the list */ /* Add the object to the list */
if (git_vector_insert(&idx->objects, entry) < 0) if (git_vector_insert(&idx->objects, entry) < 0)
goto on_error; goto on_error;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment