Commit e544a5b8 by Vicent Martí

Merge pull request #1968 from libgit2/ntk/fix/bad_index

Corrupted index is bad for your health
parents 7135e77a bd15b513
...@@ -321,6 +321,7 @@ void git_index__set_ignore_case(git_index *index, bool ignore_case) ...@@ -321,6 +321,7 @@ void git_index__set_ignore_case(git_index *index, bool ignore_case)
int git_index_open(git_index **index_out, const char *index_path) int git_index_open(git_index **index_out, const char *index_path)
{ {
git_index *index; git_index *index;
int error;
assert(index_out); assert(index_out);
...@@ -346,10 +347,15 @@ int git_index_open(git_index **index_out, const char *index_path) ...@@ -346,10 +347,15 @@ int git_index_open(git_index **index_out, const char *index_path)
index->entries_search_path = index_srch_path; index->entries_search_path = index_srch_path;
index->reuc_search = reuc_srch; index->reuc_search = reuc_srch;
if ((index_path != NULL) && ((error = git_index_read(index, true)) < 0)) {
git_index_free(index);
return error;
}
*index_out = index; *index_out = index;
GIT_REFCOUNT_INC(index); GIT_REFCOUNT_INC(index);
return (index_path != NULL) ? git_index_read(index, true) : 0; return 0;
} }
int git_index_new(git_index **out) int git_index_new(git_index **out)
......
...@@ -138,9 +138,11 @@ static int read_tree_internal(git_tree_cache **out, ...@@ -138,9 +138,11 @@ static int read_tree_internal(git_tree_cache **out,
tree->children = git__malloc(tree->children_count * sizeof(git_tree_cache *)); tree->children = git__malloc(tree->children_count * sizeof(git_tree_cache *));
GITERR_CHECK_ALLOC(tree->children); GITERR_CHECK_ALLOC(tree->children);
memset(tree->children, 0x0, tree->children_count * sizeof(git_tree_cache *));
for (i = 0; i < tree->children_count; ++i) { for (i = 0; i < tree->children_count; ++i) {
if (read_tree_internal(&tree->children[i], &buffer, buffer_end, tree) < 0) if (read_tree_internal(&tree->children[i], &buffer, buffer_end, tree) < 0)
return -1; goto corrupted;
} }
} }
...@@ -150,7 +152,7 @@ static int read_tree_internal(git_tree_cache **out, ...@@ -150,7 +152,7 @@ static int read_tree_internal(git_tree_cache **out,
corrupted: corrupted:
git_tree_cache_free(tree); git_tree_cache_free(tree);
giterr_set(GITERR_INDEX, "Corruped TREE extension in index"); giterr_set(GITERR_INDEX, "Corrupted TREE extension in index");
return -1; return -1;
} }
...@@ -162,7 +164,7 @@ int git_tree_cache_read(git_tree_cache **tree, const char *buffer, size_t buffer ...@@ -162,7 +164,7 @@ int git_tree_cache_read(git_tree_cache **tree, const char *buffer, size_t buffer
return -1; return -1;
if (buffer < buffer_end) { if (buffer < buffer_end) {
giterr_set(GITERR_INDEX, "Corruped TREE extension in index (unexpected trailing data)"); giterr_set(GITERR_INDEX, "Corrupted TREE extension in index (unexpected trailing data)");
return -1; return -1;
} }
...@@ -176,9 +178,12 @@ void git_tree_cache_free(git_tree_cache *tree) ...@@ -176,9 +178,12 @@ void git_tree_cache_free(git_tree_cache *tree)
if (tree == NULL) if (tree == NULL)
return; return;
for (i = 0; i < tree->children_count; ++i) if (tree->children != NULL) {
git_tree_cache_free(tree->children[i]); for (i = 0; i < tree->children_count; ++i)
git_tree_cache_free(tree->children[i]);
git__free(tree->children);
}
git__free(tree->children);
git__free(tree); git__free(tree);
} }
...@@ -6,6 +6,7 @@ static const size_t index_entry_count_2 = 1437; ...@@ -6,6 +6,7 @@ static const size_t index_entry_count_2 = 1437;
#define TEST_INDEX_PATH cl_fixture("testrepo.git/index") #define TEST_INDEX_PATH cl_fixture("testrepo.git/index")
#define TEST_INDEX2_PATH cl_fixture("gitgit.index") #define TEST_INDEX2_PATH cl_fixture("gitgit.index")
#define TEST_INDEXBIG_PATH cl_fixture("big.index") #define TEST_INDEXBIG_PATH cl_fixture("big.index")
#define TEST_INDEXBAD_PATH cl_fixture("bad.index")
/* Suite data */ /* Suite data */
...@@ -535,3 +536,11 @@ void test_index_tests__reload_from_disk(void) ...@@ -535,3 +536,11 @@ void test_index_tests__reload_from_disk(void)
git_index_free(write_index); git_index_free(write_index);
git_repository_free(repo); git_repository_free(repo);
} }
void test_index_tests__corrupted_extension(void)
{
/* sort the entires in an empty index */
git_index *index;
cl_git_fail_with(git_index_open(&index, TEST_INDEXBAD_PATH), GIT_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