summaryrefslogtreecommitdiff
path: root/resolve-undo.c
diff options
context:
space:
mode:
authorLibravatar Karsten Blees <karsten.blees@gmail.com>2013-11-14 20:24:37 +0100
committerLibravatar Junio C Hamano <gitster@pobox.com>2013-11-18 13:04:25 -0800
commit5699d17ee0949e6c01311a03dcfce485fcdd9b1a (patch)
treef12588558bd275204e058f2f5c7b88e003edea9e /resolve-undo.c
parentbuiltin/update-index.c: cleanup update_one (diff)
downloadtgif-5699d17ee0949e6c01311a03dcfce485fcdd9b1a.tar.xz
read-cache.c: fix memory leaks caused by removed cache entries
When cache_entry structs are removed from index_state.cache, they are not properly freed. Freeing those entries wasn't possible before because we couldn't remove them from index_state.name_hash. Now that we _do_ remove the entries from name_hash, we can also free them. Add 'free(cache_entry)' to all call sites of name-hash.c::remove_name_hash in read-cache.c (we could free() directly in remove_name_hash(), but name-hash.c isn't concerned with cache_entry allocation at all). Accessing a cache_entry after removing it from the index is now no longer allowed, as the memory has been freed. The following functions need minor fixes (typically by copying ce->name before use): - builtin/rm.c::cmd_rm - builtin/update-index.c::do_reupdate - read-cache.c::read_index_unmerged - resolve-undo.c::unmerge_index_entry_at Signed-off-by: Karsten Blees <blees@dcon.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'resolve-undo.c')
-rw-r--r--resolve-undo.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/resolve-undo.c b/resolve-undo.c
index c09b00664e..49ebaaf8d8 100644
--- a/resolve-undo.c
+++ b/resolve-undo.c
@@ -119,6 +119,7 @@ int unmerge_index_entry_at(struct index_state *istate, int pos)
struct string_list_item *item;
struct resolve_undo_info *ru;
int i, err = 0, matched;
+ char *name;
if (!istate->resolve_undo)
return pos;
@@ -138,20 +139,22 @@ int unmerge_index_entry_at(struct index_state *istate, int pos)
if (!ru)
return pos;
matched = ce->ce_flags & CE_MATCHED;
+ name = xstrdup(ce->name);
remove_index_entry_at(istate, pos);
for (i = 0; i < 3; i++) {
struct cache_entry *nce;
if (!ru->mode[i])
continue;
nce = make_cache_entry(ru->mode[i], ru->sha1[i],
- ce->name, i + 1, 0);
+ name, i + 1, 0);
if (matched)
nce->ce_flags |= CE_MATCHED;
if (add_index_entry(istate, nce, ADD_CACHE_OK_TO_ADD)) {
err = 1;
- error("cannot unmerge '%s'", ce->name);
+ error("cannot unmerge '%s'", name);
}
}
+ free(name);
if (err)
return pos;
free(ru);