From: Karsten Blees <karsten.blees@gmail.com>
To: Git List <git@vger.kernel.org>, Junio C Hamano <gitster@pobox.com>
Cc: Thomas Rast <tr@thomasrast.ch>,
Jens Lehmann <Jens.Lehmann@web.de>,
Karsten Blees <karsten.blees@gmail.com>
Subject: [PATCH v4 14/14] read-cache.c: fix memory leaks caused by removed cache entries
Date: Thu, 07 Nov 2013 15:45:01 +0100 [thread overview]
Message-ID: <527BA76D.20101@gmail.com> (raw)
In-Reply-To: <527BA483.6040803@gmail.com>
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>
---
builtin/rm.c | 2 +-
builtin/update-index.c | 5 ++++-
read-cache.c | 8 ++++++--
resolve-undo.c | 7 +++++--
4 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/builtin/rm.c b/builtin/rm.c
index 3a0e0ea..171f37c 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -311,7 +311,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
if (!match_pathspec_depth(&pathspec, ce->name, ce_namelen(ce), 0, seen))
continue;
ALLOC_GROW(list.entry, list.nr + 1, list.alloc);
- list.entry[list.nr].name = ce->name;
+ list.entry[list.nr].name = xstrdup(ce->name);
list.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode);
if (list.entry[list.nr++].is_submodule &&
!is_staging_gitmodules_ok())
diff --git a/builtin/update-index.c b/builtin/update-index.c
index b654d27..acd992d 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -559,6 +559,7 @@ static int do_reupdate(int ac, const char **av,
const struct cache_entry *ce = active_cache[pos];
struct cache_entry *old = NULL;
int save_nr;
+ const char *path;
if (ce_stage(ce) || !ce_path_match(ce, &pathspec))
continue;
@@ -575,7 +576,9 @@ static int do_reupdate(int ac, const char **av,
* or worse yet 'allow_replace', active_nr may decrease.
*/
save_nr = active_nr;
- update_one(ce->name);
+ path = xstrdup(ce->name);
+ update_one(path);
+ free(path);
if (save_nr != active_nr)
goto redo;
}
diff --git a/read-cache.c b/read-cache.c
index 00af9ad..3f735f3 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -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;
diff --git a/resolve-undo.c b/resolve-undo.c
index c09b006..49ebaaf 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);
--
1.8.4.msysgit.0.12.g88f5ed0
next prev parent reply other threads:[~2013-11-07 14:45 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-11-07 14:32 [PATCH v4 00/14] New hash table implementation Karsten Blees
2013-11-07 14:33 ` [PATCH v4 01/14] submodule: don't access the .gitmodules cache entry after removing it Karsten Blees
2013-11-07 22:27 ` Heiko Voigt
2013-11-07 14:34 ` [PATCH v4 02/14] add a hashtable implementation that supports O(1) removal Karsten Blees
2013-11-07 21:40 ` Junio C Hamano
2013-11-08 10:27 ` Karsten Blees
2013-11-08 16:45 ` Philip Oakley
2013-11-08 17:08 ` Junio C Hamano
2013-11-13 16:37 ` Karsten Blees
2013-11-07 14:35 ` [PATCH v4 03/14] buitin/describe.c: use new hash map implementation Karsten Blees
2013-11-07 14:36 ` [PATCH v4 04/14] diffcore-rename.c: move code around to prepare for the next patch Karsten Blees
2013-11-07 14:36 ` [PATCH v4 05/14] diffcore-rename.c: simplify finding exact renames Karsten Blees
2013-11-07 14:37 ` [PATCH v4 06/14] diffcore-rename.c: use new hash map implementation Karsten Blees
2013-11-07 14:38 ` [PATCH v4 07/14] name-hash.c: use new hash map implementation for directories Karsten Blees
2013-11-07 14:38 ` [PATCH v4 08/14] name-hash.c: remove unreferenced directory entries Karsten Blees
2013-11-07 14:39 ` [PATCH v4 09/14] name-hash.c: use new hash map implementation for cache entries Karsten Blees
2013-11-07 14:39 ` [PATCH v4 10/14] name-hash.c: remove cache entries instead of marking them CE_UNHASHED Karsten Blees
2013-11-07 14:40 ` [PATCH v4 11/14] remove old hash.[ch] implementation Karsten Blees
2013-11-07 14:43 ` [PATCH v4 12/14] fix 'git update-index --verbose --again' output Karsten Blees
2013-11-07 22:12 ` Junio C Hamano
2013-11-08 10:27 ` Karsten Blees
2013-11-07 14:44 ` [PATCH v4 13/14] builtin/update-index.c: cleanup update_one Karsten Blees
2013-11-07 21:40 ` Junio C Hamano
2013-11-08 10:27 ` Karsten Blees
2013-11-07 14:45 ` Karsten Blees [this message]
2013-11-07 21:40 ` [PATCH v4 14/14] read-cache.c: fix memory leaks caused by removed cache entries Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=527BA76D.20101@gmail.com \
--to=karsten.blees@gmail.com \
--cc=Jens.Lehmann@web.de \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=tr@thomasrast.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).