summaryrefslogtreecommitdiff
path: root/src/index.c
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2014-03-14 21:59:26 -0700
committerRussell Belfer <rb@github.com>2014-04-17 14:43:46 -0700
commitaba6b5edbd1d1f999086669eb8e2f553af0ac300 (patch)
treea275b42fe9872a29b2e5f9ce0f0aab9b806733fe /src/index.c
parentcef170abf2704a3e3aa109020f7041e43b5e4f71 (diff)
downloadlibgit2-aba6b5edbd1d1f999086669eb8e2f553af0ac300.tar.gz
Fix leak in git_index_conflict_cleanup
I introduced a leak into conflict cleanup by removing items from inside the git_vector_remove_matching call. This simplifies the code to just use one common way for the two conflict cleanup APIs. When an index has an active snapshot, removing an item can cause an error (inserting into the deferred deletion vector), so I made the git_index_conflict_cleanup API return an error code. I felt like this wasn't so bad since it is just like the other APIs. I fixed up a couple of comments while I was changing the header.
Diffstat (limited to 'src/index.c')
-rw-r--r--src/index.c32
1 files changed, 10 insertions, 22 deletions
diff --git a/src/index.c b/src/index.c
index 10fb1fea7..27a557cfb 100644
--- a/src/index.c
+++ b/src/index.c
@@ -1317,15 +1317,13 @@ int git_index_conflict_get(
return 0;
}
-int git_index_conflict_remove(git_index *index, const char *path)
+static int index_conflict_remove(git_index *index, const char *path)
{
- size_t pos;
+ size_t pos = 0;
git_index_entry *conflict_entry;
int error = 0;
- assert(index && path);
-
- if (git_index_find(&pos, index, path) < 0)
+ if (path != NULL && git_index_find(&pos, index, path) < 0)
return GIT_ENOTFOUND;
if (git_mutex_lock(&index->lock) < 0) {
@@ -1335,7 +1333,8 @@ int git_index_conflict_remove(git_index *index, const char *path)
while ((conflict_entry = git_vector_get(&index->entries, pos)) != NULL) {
- if (index->entries_cmp_path(conflict_entry->path, path) != 0)
+ if (path != NULL &&
+ index->entries_cmp_path(conflict_entry->path, path) != 0)
break;
if (GIT_IDXENTRY_STAGE(conflict_entry) == 0) {
@@ -1352,27 +1351,16 @@ int git_index_conflict_remove(git_index *index, const char *path)
return error;
}
-static int index_conflicts_match(const git_vector *v, size_t idx, void *p)
+int git_index_conflict_remove(git_index *index, const char *path)
{
- git_index *index = p;
- git_index_entry *entry = git_vector_get(v, idx);
-
- if (GIT_IDXENTRY_STAGE(entry) > 0 &&
- !index_remove_entry(index, idx))
- return 1;
-
- return 0;
+ assert(index && path);
+ return index_conflict_remove(index, path);
}
-void git_index_conflict_cleanup(git_index *index)
+int git_index_conflict_cleanup(git_index *index)
{
assert(index);
-
- if (git_mutex_lock(&index->lock) < 0)
- return;
- git_vector_remove_matching(&index->entries, index_conflicts_match, index);
- index_free_deleted(index);
- git_mutex_unlock(&index->lock);
+ return index_conflict_remove(index, NULL);
}
int git_index_has_conflicts(const git_index *index)