Skip to content

Commit 1da1e07

Browse files
peffgitster
authored andcommitted
clean up name allocation in prepare_revision_walk
When we enter prepare_revision_walk, we have zero or more entries in our "pending" array. We disconnect that array from the rev_info, and then process each entry: 1. If the entry is a commit and the --source option is in effect, we keep a pointer to the object name. 2. Otherwise, we re-add the item to the pending list with a blank name. We then throw away the old array by freeing the array itself, but do not touch the "name" field of each entry. For any items of type (2), we leak the memory associated with the name. This commit fixes that by calling object_array_clear, which handles the cleanup for us. That breaks (1), though, because it depends on the memory pointed to by the name to last forever. We can solve that by making a copy of the name. This is slightly less efficient, but it shouldn't matter in practice, as we do it only for the tip commits of the traversal. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 46be823 commit 1da1e07

File tree

1 file changed

+7
-7
lines changed

1 file changed

+7
-7
lines changed

revision.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@ static struct commit *handle_commit(struct rev_info *revs,
300300
revs->limited = 1;
301301
}
302302
if (revs->show_source && !commit->util)
303-
commit->util = (void *) name;
303+
commit->util = xstrdup(name);
304304
return commit;
305305
}
306306

@@ -2656,26 +2656,26 @@ void reset_revision_walk(void)
26562656

26572657
int prepare_revision_walk(struct rev_info *revs)
26582658
{
2659-
int nr = revs->pending.nr;
2660-
struct object_array_entry *e, *list;
2659+
int i;
2660+
struct object_array old_pending;
26612661
struct commit_list **next = &revs->commits;
26622662

2663-
e = list = revs->pending.objects;
2663+
memcpy(&old_pending, &revs->pending, sizeof(old_pending));
26642664
revs->pending.nr = 0;
26652665
revs->pending.alloc = 0;
26662666
revs->pending.objects = NULL;
2667-
while (--nr >= 0) {
2667+
for (i = 0; i < old_pending.nr; i++) {
2668+
struct object_array_entry *e = old_pending.objects + i;
26682669
struct commit *commit = handle_commit(revs, e->item, e->name);
26692670
if (commit) {
26702671
if (!(commit->object.flags & SEEN)) {
26712672
commit->object.flags |= SEEN;
26722673
next = commit_list_append(commit, next);
26732674
}
26742675
}
2675-
e++;
26762676
}
26772677
if (!revs->leak_pending)
2678-
free(list);
2678+
object_array_clear(&old_pending);
26792679

26802680
/* Signal whether we need per-parent treesame decoration */
26812681
if (revs->simplify_merges ||

0 commit comments

Comments
 (0)