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>
This commit is contained in:

committed by
Junio C Hamano

parent
6bb69077b7
commit
5699d17ee0
@ -47,6 +47,7 @@ static void replace_index_entry(struct index_state *istate, int nr, struct cache
|
||||
struct cache_entry *old = istate->cache[nr];
|
||||
|
||||
remove_name_hash(istate, old);
|
||||
free(old);
|
||||
set_index_entry(istate, nr, ce);
|
||||
istate->cache_changed = 1;
|
||||
}
|
||||
@ -478,6 +479,7 @@ int remove_index_entry_at(struct index_state *istate, int pos)
|
||||
|
||||
record_resolve_undo(istate, ce);
|
||||
remove_name_hash(istate, ce);
|
||||
free(ce);
|
||||
istate->cache_changed = 1;
|
||||
istate->cache_nr--;
|
||||
if (pos >= istate->cache_nr)
|
||||
@ -499,8 +501,10 @@ void remove_marked_cache_entries(struct index_state *istate)
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = j = 0; i < istate->cache_nr; i++) {
|
||||
if (ce_array[i]->ce_flags & CE_REMOVE)
|
||||
if (ce_array[i]->ce_flags & CE_REMOVE) {
|
||||
remove_name_hash(istate, ce_array[i]);
|
||||
free(ce_array[i]);
|
||||
}
|
||||
else
|
||||
ce_array[j++] = ce_array[i];
|
||||
}
|
||||
@ -1894,7 +1898,7 @@ int read_index_unmerged(struct index_state *istate)
|
||||
new_ce->ce_mode = ce->ce_mode;
|
||||
if (add_index_entry(istate, new_ce, 0))
|
||||
return error("%s: cannot drop to stage #0",
|
||||
ce->name);
|
||||
new_ce->name);
|
||||
i = index_name_pos(istate, new_ce->name, len);
|
||||
}
|
||||
return unmerged;
|
||||
|
Reference in New Issue
Block a user