Commit bf3ee3cf by Vicent Martí

Merge pull request #1705 from arrbee/avoid-index-double-free

Try harder not to double free index entries
parents bf730611 178aa39c
...@@ -261,6 +261,22 @@ static int reuc_icmp(const void *a, const void *b) ...@@ -261,6 +261,22 @@ static int reuc_icmp(const void *a, const void *b)
return strcasecmp(info_a->path, info_b->path); return strcasecmp(info_a->path, info_b->path);
} }
static void index_entry_reuc_free(git_index_reuc_entry *reuc)
{
if (!reuc)
return;
git__free(reuc->path);
git__free(reuc);
}
static void index_entry_free(git_index_entry *entry)
{
if (!entry)
return;
git__free(entry->path);
git__free(entry);
}
static unsigned int index_create_mode(unsigned int mode) static unsigned int index_create_mode(unsigned int mode)
{ {
if (S_ISLNK(mode)) if (S_ISLNK(mode))
...@@ -367,11 +383,8 @@ static void index_entries_free(git_vector *entries) ...@@ -367,11 +383,8 @@ static void index_entries_free(git_vector *entries)
{ {
size_t i; size_t i;
for (i = 0; i < entries->length; ++i) { for (i = 0; i < entries->length; ++i)
git_index_entry *e = git_vector_get(entries, i); index_entry_free(git__swap(entries->contents[i], NULL));
git__free(e->path);
git__free(e);
}
git_vector_clear(entries); git_vector_clear(entries);
} }
...@@ -670,15 +683,6 @@ static int index_entry_reuc_init(git_index_reuc_entry **reuc_out, ...@@ -670,15 +683,6 @@ static int index_entry_reuc_init(git_index_reuc_entry **reuc_out,
return 0; return 0;
} }
static void index_entry_reuc_free(git_index_reuc_entry *reuc)
{
if (!reuc)
return;
git__free(reuc->path);
git__free(reuc);
}
static git_index_entry *index_entry_dup(const git_index_entry *source_entry) static git_index_entry *index_entry_dup(const git_index_entry *source_entry)
{ {
git_index_entry *entry; git_index_entry *entry;
...@@ -697,14 +701,6 @@ static git_index_entry *index_entry_dup(const git_index_entry *source_entry) ...@@ -697,14 +701,6 @@ static git_index_entry *index_entry_dup(const git_index_entry *source_entry)
return entry; return entry;
} }
static void index_entry_free(git_index_entry *entry)
{
if (!entry)
return;
git__free(entry->path);
git__free(entry);
}
static int index_insert(git_index *index, git_index_entry *entry, int replace) static int index_insert(git_index *index, git_index_entry *entry, int replace)
{ {
size_t path_length, position; size_t path_length, position;
...@@ -1357,14 +1353,11 @@ int git_index_reuc_remove(git_index *index, size_t position) ...@@ -1357,14 +1353,11 @@ int git_index_reuc_remove(git_index *index, size_t position)
void git_index_reuc_clear(git_index *index) void git_index_reuc_clear(git_index *index)
{ {
size_t i; size_t i;
git_index_reuc_entry *reuc;
assert(index); assert(index);
git_vector_foreach(&index->reuc, i, reuc) { for (i = 0; i < index->reuc.length; ++i)
git__free(reuc->path); index_entry_reuc_free(git__swap(index->reuc.contents[i], NULL));
git__free(reuc);
}
git_vector_clear(&index->reuc); git_vector_clear(&index->reuc);
} }
...@@ -1958,8 +1951,9 @@ int git_index_entry_stage(const git_index_entry *entry) ...@@ -1958,8 +1951,9 @@ int git_index_entry_stage(const git_index_entry *entry)
} }
typedef struct read_tree_data { typedef struct read_tree_data {
git_index *index;
git_vector *old_entries; git_vector *old_entries;
git_vector *new_entries;
git_vector_cmp entries_search;
} read_tree_data; } read_tree_data;
static int read_tree_cb( static int read_tree_cb(
...@@ -1990,7 +1984,7 @@ static int read_tree_cb( ...@@ -1990,7 +1984,7 @@ static int read_tree_cb(
skey.stage = 0; skey.stage = 0;
if (!git_vector_bsearch2( if (!git_vector_bsearch2(
&pos, data->old_entries, data->index->entries_search, &skey) && &pos, data->old_entries, data->entries_search, &skey) &&
(old_entry = git_vector_get(data->old_entries, pos)) != NULL && (old_entry = git_vector_get(data->old_entries, pos)) != NULL &&
entry->mode == old_entry->mode && entry->mode == old_entry->mode &&
git_oid_equal(&entry->oid, &old_entry->oid)) git_oid_equal(&entry->oid, &old_entry->oid))
...@@ -2008,7 +2002,7 @@ static int read_tree_cb( ...@@ -2008,7 +2002,7 @@ static int read_tree_cb(
entry->path = git_buf_detach(&path); entry->path = git_buf_detach(&path);
git_buf_free(&path); git_buf_free(&path);
if (git_vector_insert(&data->index->entries, entry) < 0) { if (git_vector_insert(data->new_entries, entry) < 0) {
index_entry_free(entry); index_entry_free(entry);
return -1; return -1;
} }
...@@ -2022,22 +2016,22 @@ int git_index_read_tree(git_index *index, const git_tree *tree) ...@@ -2022,22 +2016,22 @@ int git_index_read_tree(git_index *index, const git_tree *tree)
git_vector entries = GIT_VECTOR_INIT; git_vector entries = GIT_VECTOR_INIT;
read_tree_data data; read_tree_data data;
git_vector_sort(&index->entries); git_vector_set_cmp(&entries, index->entries._cmp); /* match sort */
git_vector_set_cmp(&entries, index->entries._cmp);
git_vector_swap(&entries, &index->entries);
git_index_clear(index); data.old_entries = &index->entries;
data.new_entries = &entries;
data.entries_search = index->entries_search;
data.index = index; git_vector_sort(&index->entries);
data.old_entries = &entries;
error = git_tree_walk(tree, GIT_TREEWALK_POST, read_tree_cb, &data); error = git_tree_walk(tree, GIT_TREEWALK_POST, read_tree_cb, &data);
index_entries_free(&entries); git_vector_sort(&entries);
git_vector_free(&entries);
git_vector_sort(&index->entries); git_index_clear(index);
git_vector_swap(&entries, &index->entries);
git_vector_free(&entries);
return error; return 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