Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@elego.de>2012-11-30 20:25:50 +0400
committerCarlos Martín Nieto <cmn@dwim.me>2012-11-30 22:16:39 +0400
commit3908c254aac0532baf5a2f6a96603d946edc0510 (patch)
tree58d7eab08ddad1524b0d55a6ae1eb640f1063891 /src/indexer.c
parent5a3ad89dbd8954b87e14a20ee2dcb282528d4531 (diff)
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.
Diffstat (limited to 'src/indexer.c')
-rw-r--r--src/indexer.c45
1 files changed, 26 insertions, 19 deletions
diff --git a/src/indexer.c b/src/indexer.c
index 726667665..f78ca5774 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -261,18 +261,38 @@ static int read_object_stream(git_packfile_stream *stream)
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)
{
int i;
git_oid oid;
- void *packed;
- unsigned int left;
struct entry *entry;
git_off_t entry_size;
- git_mwindow *w = NULL;
struct git_pack_entry *pentry;
git_hash_ctx *ctx = &idx->hash_ctx;
- git_mwindow_file *mwf = &idx->pack->mwf;
git_off_t entry_start = idx->entry_start;
entry = git__calloc(1, sizeof(*entry));
@@ -298,15 +318,10 @@ static int store_object(git_indexer_stream *idx)
}
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 (packed == NULL)
+ if (crc_object(&entry->crc, &idx->pack->mwf, entry_start, entry_size) < 0)
goto on_error;
- entry->crc = htonl(crc32(entry->crc, packed, (uInt)entry_size));
- git_mwindow_close(&w);
-
/* Add the object to the list */
if (git_vector_insert(&idx->objects, entry) < 0)
goto on_error;
@@ -327,12 +342,8 @@ static int hash_and_save(git_indexer_stream *idx, git_rawobj *obj, git_off_t ent
{
int i;
git_oid oid;
- void *packed;
size_t entry_size;
- unsigned int left;
struct entry *entry;
- git_mwindow *w = NULL;
- git_mwindow_file *mwf = &idx->pack->mwf;
struct git_pack_entry *pentry;
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
entry->crc = crc32(0L, Z_NULL, 0);
entry_size = (size_t)(idx->off - entry_start);
- packed = git_mwindow_open(mwf, &w, entry_start, entry_size, &left);
- if (packed == NULL)
+ if (crc_object(&entry->crc, &idx->pack->mwf, entry_start, entry_size) < 0)
goto on_error;
- entry->crc = htonl(crc32(entry->crc, packed, (uInt)entry_size));
- git_mwindow_close(&w);
-
/* Add the object to the list */
if (git_vector_insert(&idx->objects, entry) < 0)
goto on_error;