From 5c6ae0099977e2e950e98b9bf07ce9683b6df059 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Mon, 18 Jul 2011 01:54:40 +0300 Subject: [PATCH 1/2] refs: fix memory leak on rename Current implementation of git_reference_rename() removes 'ref' from loose cache, but not frees it. In result 'ref' is not reachable any more and we have got memory leak. Let's re-add 'ref' with corrected name to loose cache instead of 'new_ref' and free 'new_ref' properly. 'rollback' path seems leak too. git_reference_rename() need to be rewritten for proper resource management. Signed-off-by: Kirill A. Shutemov --- src/refs.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/refs.c b/src/refs.c index 78bab885e..8022c2b2a 100644 --- a/src/refs.c +++ b/src/refs.c @@ -1404,7 +1404,14 @@ int git_reference_rename(git_reference *ref, const char *new_name, int force) free(ref->name); ref->name = new_ref->name; - if ((error = git_hashtable_insert2(ref->owner->references.loose_cache, new_ref->name, new_ref, (void **)&old_ref)) < GIT_SUCCESS) + /* + * No need in new_ref anymore. We created it to fix the change on disk. + * TODO: Refactoring required. + */ + new_ref->name = NULL; + reference_free(new_ref); + + if ((error = git_hashtable_insert2(ref->owner->references.loose_cache, ref->name, ref, (void **)&old_ref)) < GIT_SUCCESS) goto rollback; /* @@ -1417,7 +1424,7 @@ int git_reference_rename(git_reference *ref, const char *new_name, int force) head_target = git_reference_target(head); if (head_target && !strcmp(head_target, old_name)) - if ((error = git_reference_create_symbolic(&head, new_ref->owner, "HEAD", new_ref->name, 1)) < GIT_SUCCESS) + if ((error = git_reference_create_symbolic(&head, ref->owner, "HEAD", ref->name, 1)) < GIT_SUCCESS) goto rollback; cleanup: From 26b1b15767a6e7b6401884611437ca25fe5555bb Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Mon, 18 Jul 2011 02:05:23 +0300 Subject: [PATCH 2/2] index: fix memory leak We need really free vectors on index freeing, not only clear. Signed-off-by: Kirill A. Shutemov --- src/index.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.c b/src/index.c index 2fa9c1922..6390da3d7 100644 --- a/src/index.c +++ b/src/index.c @@ -196,6 +196,8 @@ void git_index_free(git_index *index) return; git_index_clear(index); + git_vector_free(&index->entries); + git_vector_free(&index->unmerged); free(index->index_file_path); free(index);