summaryrefslogtreecommitdiffstats
path: root/fast-import.c
diff options
context:
space:
mode:
authorShawn O. Pearce <spearce@spearce.org>2006-08-23 07:33:47 +0200
committerShawn O. Pearce <spearce@spearce.org>2007-01-14 08:15:05 +0100
commitafde8dd96dbb81688d7cb22330e4fffcfc7def21 (patch)
tree4ea2cde49b9b71f5a14a7e731d58c248b7ac475b /fast-import.c
parentAllow symlink blobs in trees during fast-import. (diff)
downloadgit-afde8dd96dbb81688d7cb22330e4fffcfc7def21.tar.xz
git-afde8dd96dbb81688d7cb22330e4fffcfc7def21.zip
Fixed segfault in fast-import after growing a tree.
Growing a tree caused all subtrees to be deallocated and put back into the free list yet those subtree's contents were still actively in use. Consequently they were doled out again and got stomped on elsewhere. Releasing a tree is now performed in two parts, either releasing only the content array or releasing the content array and recursively releasing the subtree(s). Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'fast-import.c')
-rw-r--r--fast-import.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/fast-import.c b/fast-import.c
index 7d1ee1dad9..4c2431f0b0 100644
--- a/fast-import.c
+++ b/fast-import.c
@@ -420,11 +420,16 @@ static void release_tree_content(struct tree_content *t)
{
struct avail_tree_content *f = (struct avail_tree_content*)t;
unsigned int hc = hc_entries(f->entry_capacity);
+ f->next_avail = avail_tree_table[hc];
+ avail_tree_table[hc] = f;
+}
+
+static void release_tree_content_recursive(struct tree_content *t)
+{
unsigned int i;
for (i = 0; i < t->entry_count; i++)
release_tree_entry(t->entries[i]);
- f->next_avail = avail_tree_table[hc];
- avail_tree_table[hc] = f;
+ release_tree_content(t);
}
static struct tree_content* grow_tree_content(
@@ -459,7 +464,7 @@ static struct tree_entry* new_tree_entry()
static void release_tree_entry(struct tree_entry *e)
{
if (e->tree)
- release_tree_content(e->tree);
+ release_tree_content_recursive(e->tree);
*((void**)e) = avail_tree_entry;
avail_tree_entry = e;
}
@@ -720,7 +725,7 @@ static int tree_content_set(
e->mode = mode;
memcpy(e->sha1, sha1, 20);
if (e->tree) {
- release_tree_content(e->tree);
+ release_tree_content_recursive(e->tree);
e->tree = NULL;
}
memcpy(root->sha1, null_sha1, 20);
@@ -986,7 +991,7 @@ static void unload_one_branch()
}
e->active_next_branch = NULL;
if (e->branch_tree.tree) {
- release_tree_content(e->branch_tree.tree);
+ release_tree_content_recursive(e->branch_tree.tree);
e->branch_tree.tree = NULL;
}
cur_active_branches--;