diff options
| author | Vicent Martà <tanoku@gmail.com> | 2012-01-19 11:38:09 -0800 |
|---|---|---|
| committer | Vicent Martà <tanoku@gmail.com> | 2012-01-19 11:38:09 -0800 |
| commit | 881e3da012453941eb2b237d85ab5636eea21c76 (patch) | |
| tree | d570020a769280e0ca6ab4e87d79604d945df0c1 /src | |
| parent | d0ec3fb8f07988779783f69ab6cf5f3431c7aa3e (diff) | |
| parent | 20c50b9e16c19bbbf7cf38bb4bd3177596bce61b (diff) | |
| download | libgit2-881e3da012453941eb2b237d85ab5636eea21c76.tar.gz | |
Merge pull request #538 from carlosmn/ref-noleak
Don't leak when deleting or removing refs
Diffstat (limited to 'src')
| -rw-r--r-- | src/hashtable.c | 3 | ||||
| -rw-r--r-- | src/hashtable.h | 10 | ||||
| -rw-r--r-- | src/refs.c | 6 |
3 files changed, 15 insertions, 4 deletions
diff --git a/src/hashtable.c b/src/hashtable.c index f836f166d..89c44ba9e 100644 --- a/src/hashtable.c +++ b/src/hashtable.c @@ -213,7 +213,7 @@ void *git_hashtable_lookup(git_hashtable *self, const void *key) return NULL; } -int git_hashtable_remove(git_hashtable *self, const void *key) +int git_hashtable_remove2(git_hashtable *self, const void *key, void **old_value) { int hash_id; git_hashtable_node *node; @@ -223,6 +223,7 @@ int git_hashtable_remove(git_hashtable *self, const void *key) for (hash_id = 0; hash_id < GIT_HASHTABLE_HASHES; ++hash_id) { node = node_with_hash(self, key, hash_id); if (node->key && self->key_equal(key, node->key) == 0) { + *old_value = node->value; node->key = NULL; node->value = NULL; self->key_count--; diff --git a/src/hashtable.h b/src/hashtable.h index 485b17aa6..cd458eb17 100644 --- a/src/hashtable.h +++ b/src/hashtable.h @@ -42,7 +42,15 @@ git_hashtable *git_hashtable_alloc(size_t min_size, git_hash_ptr hash, git_hash_keyeq_ptr key_eq); void *git_hashtable_lookup(git_hashtable *h, const void *key); -int git_hashtable_remove(git_hashtable *table, const void *key); +int git_hashtable_remove2(git_hashtable *table, const void *key, void **old_value); + +GIT_INLINE(int) git_hashtable_remove(git_hashtable *table, const void *key) +{ + void *_unused; + return git_hashtable_remove2(table, key, &_unused); +} + + void git_hashtable_free(git_hashtable *h); void git_hashtable_clear(git_hashtable *h); int git_hashtable_merge(git_hashtable *self, git_hashtable *other); diff --git a/src/refs.c b/src/refs.c index 340841cc6..86e5f5dba 100644 --- a/src/refs.c +++ b/src/refs.c @@ -984,14 +984,16 @@ static int reference_delete(git_reference *ref) * We need to reload the packfile, remove the reference from the * packing list, and repack */ if (ref->flags & GIT_REF_PACKED) { + struct packref *packref; /* load the existing packfile */ if ((error = packed_load(ref->owner)) < GIT_SUCCESS) return git__rethrow(error, "Failed to delete reference"); - if (git_hashtable_remove(ref->owner->references.packfile, - ref->name) < GIT_SUCCESS) + if (git_hashtable_remove2(ref->owner->references.packfile, + ref->name, (void **) &packref) < GIT_SUCCESS) return git__throw(GIT_ENOTFOUND, "Reference not found"); + git__free (packref); error = packed_write(ref->owner); /* If the reference is loose, we can just remove the reference |
