Commit b206d74ccaca2bca33e5db85fb6c1e4b8fc54541

Vicent Martí 2012-05-16T04:40:32

Merge pull request #703 from carlosmn/consistency A few indexer consistency checks

diff --git a/include/git2/errors.h b/include/git2/errors.h
index 0406c16..8563438 100644
--- a/include/git2/errors.h
+++ b/include/git2/errors.h
@@ -62,6 +62,7 @@ typedef enum {
 	GITERR_NET,
 	GITERR_TAG,
 	GITERR_TREE,
+	GITERR_INDEXER,
 } git_error_class;
 
 /**
diff --git a/src/indexer.c b/src/indexer.c
index 0baa194..01bec08 100644
--- a/src/indexer.c
+++ b/src/indexer.c
@@ -110,12 +110,12 @@ static int parse_header(struct git_pack_header *hdr, struct git_pack_file *pack)
 	}
 
 	if (hdr->hdr_signature != ntohl(PACK_SIGNATURE)) {
-		giterr_set(GITERR_INVALID, "Wrong pack signature");
+		giterr_set(GITERR_INDEXER, "Wrong pack signature");
 		return -1;
 	}
 
 	if (!pack_version_ok(hdr->hdr_version)) {
-		giterr_set(GITERR_INVALID, "Wrong pack version");
+		giterr_set(GITERR_INDEXER, "Wrong pack version");
 		return -1;
 	}
 
@@ -248,7 +248,7 @@ static int hash_and_save(git_indexer_stream *idx, git_rawobj *obj, git_off_t ent
 
 	/* FIXME: Parse the object instead of hashing it */
 	if (git_odb__hashobj(&oid, obj) < 0) {
-		giterr_set(GITERR_INVALID, "Failed to hash object");
+		giterr_set(GITERR_INDEXER, "Failed to hash object");
 		return -1;
 	}
 
@@ -441,10 +441,21 @@ int git_indexer_stream_finalize(git_indexer_stream *idx, git_indexer_stats *stat
 	git_oid file_hash;
 	SHA_CTX ctx;
 
+	/* Test for this before resolve_deltas(), as it plays with idx->off */
+	if (idx->off < idx->pack->mwf.size - GIT_OID_RAWSZ) {
+		giterr_set(GITERR_INDEXER, "Indexing error: junk at the end of the pack");
+		return -1;
+	}
+
 	if (idx->deltas.length > 0)
 		if (resolve_deltas(idx, stats) < 0)
 			return -1;
 
+	if (stats->processed != stats->total) {
+		giterr_set(GITERR_INDEXER, "Indexing error: early EOF");
+		return -1;
+	}
+
 	git_vector_sort(&idx->objects);
 
 	git_buf_sets(&filename, idx->pack->pack_name);
@@ -583,7 +594,7 @@ int git_indexer_new(git_indexer **out, const char *packname)
 	assert(out && packname);
 
 	if (git_path_root(packname) < 0) {
-		giterr_set(GITERR_INVALID, "Path is not absolute");
+		giterr_set(GITERR_INDEXER, "Path is not absolute");
 		return -1;
 	}
 
@@ -815,7 +826,7 @@ int git_indexer_run(git_indexer *idx, git_indexer_stats *stats)
 		/* FIXME: Parse the object instead of hashing it */
 		error = git_odb__hashobj(&oid, &obj);
 		if (error < 0) {
-			giterr_set(GITERR_INVALID, "Failed to hash object");
+			giterr_set(GITERR_INDEXER, "Failed to hash object");
 			goto cleanup;
 		}