Skip to content

Commit 1c41d28

Browse files
Martin Ågrengitster
authored andcommitted
unpack_trees_options: free messages when done
The strings allocated in `setup_unpack_trees_porcelain()` are never freed. Provide a function `clear_unpack_trees_porcelain()` to do so and call it where we use `setup_unpack_trees_porcelain()`. The only non-trivial user is `unpack_trees_start()`, where we should place the new call in `unpack_trees_finish()`. We keep the string pointers in an array, mixing pointers to static memory and memory that we allocate on the heap. We also keep several copies of the individual pointers. So we need to make sure that we do not free what we must not free and that we do not double-free. Let a separate argv_array take ownership of all the strings we create so that we can easily free them. Zero the whole array of string pointers to make sure that we do not leave any dangling pointers. Note that we only take responsibility for the memory allocated in `setup_unpack_trees_porcelain()` and not any other members of the `struct unpack_trees_options`. Helped-by: Junio C Hamano <[email protected]> Signed-off-by: Junio C Hamano <[email protected]> Signed-off-by: Martin Ågren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 342c513 commit 1c41d28

File tree

5 files changed

+26
-4
lines changed

5 files changed

+26
-4
lines changed

builtin/checkout.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,7 @@ static int merge_working_tree(const struct checkout_opts *opts,
526526
init_tree_desc(&trees[1], tree->buffer, tree->size);
527527

528528
ret = unpack_trees(2, trees, &topts);
529+
clear_unpack_trees_porcelain(&topts);
529530
if (ret == -1) {
530531
/*
531532
* Unpack couldn't do a trivial merge; either

merge-recursive.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ static int unpack_trees_start(struct merge_options *o,
382382
static void unpack_trees_finish(struct merge_options *o)
383383
{
384384
discard_index(&o->orig_index);
385+
clear_unpack_trees_porcelain(&o->unpack_opts);
385386
}
386387

387388
struct tree *write_tree_from_memory(struct merge_options *o)

merge.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,8 +130,11 @@ int checkout_fast_forward(const struct object_id *head,
130130

131131
if (unpack_trees(nr_trees, t, &opts)) {
132132
rollback_lock_file(&lock_file);
133+
clear_unpack_trees_porcelain(&opts);
133134
return -1;
134135
}
136+
clear_unpack_trees_porcelain(&opts);
137+
135138
if (write_locked_index(&the_index, &lock_file, COMMIT_LOCK))
136139
return error(_("unable to write new index file"));
137140
return 0;

unpack-trees.c

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#define NO_THE_INDEX_COMPATIBILITY_MACROS
22
#include "cache.h"
3+
#include "argv-array.h"
34
#include "repository.h"
45
#include "config.h"
56
#include "dir.h"
@@ -103,6 +104,8 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
103104
const char **msgs = opts->msgs;
104105
const char *msg;
105106

107+
argv_array_init(&opts->msgs_to_free);
108+
106109
if (!strcmp(cmd, "checkout"))
107110
msg = advice_commit_before_merge
108111
? _("Your local changes to the following files would be overwritten by checkout:\n%%s"
@@ -119,7 +122,7 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
119122
"Please commit your changes or stash them before you %s.")
120123
: _("Your local changes to the following files would be overwritten by %s:\n%%s");
121124
msgs[ERROR_WOULD_OVERWRITE] = msgs[ERROR_NOT_UPTODATE_FILE] =
122-
xstrfmt(msg, cmd, cmd);
125+
argv_array_pushf(&opts->msgs_to_free, msg, cmd, cmd);
123126

124127
msgs[ERROR_NOT_UPTODATE_DIR] =
125128
_("Updating the following directories would lose untracked files in them:\n%s");
@@ -139,7 +142,8 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
139142
? _("The following untracked working tree files would be removed by %s:\n%%s"
140143
"Please move or remove them before you %s.")
141144
: _("The following untracked working tree files would be removed by %s:\n%%s");
142-
msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] = xstrfmt(msg, cmd, cmd);
145+
msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] =
146+
argv_array_pushf(&opts->msgs_to_free, msg, cmd, cmd);
143147

144148
if (!strcmp(cmd, "checkout"))
145149
msg = advice_commit_before_merge
@@ -156,7 +160,8 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
156160
? _("The following untracked working tree files would be overwritten by %s:\n%%s"
157161
"Please move or remove them before you %s.")
158162
: _("The following untracked working tree files would be overwritten by %s:\n%%s");
159-
msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] = xstrfmt(msg, cmd, cmd);
163+
msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] =
164+
argv_array_pushf(&opts->msgs_to_free, msg, cmd, cmd);
160165

161166
/*
162167
* Special case: ERROR_BIND_OVERLAP refers to a pair of paths, we
@@ -179,6 +184,12 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
179184
opts->unpack_rejects[i].strdup_strings = 1;
180185
}
181186

187+
void clear_unpack_trees_porcelain(struct unpack_trees_options *opts)
188+
{
189+
argv_array_clear(&opts->msgs_to_free);
190+
memset(opts->msgs, 0, sizeof(opts->msgs));
191+
}
192+
182193
static int do_add_entry(struct unpack_trees_options *o, struct cache_entry *ce,
183194
unsigned int set, unsigned int clear)
184195
{

unpack-trees.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define UNPACK_TREES_H
33

44
#include "tree-walk.h"
5-
#include "string-list.h"
5+
#include "argv-array.h"
66

77
#define MAX_UNPACK_TREES 8
88

@@ -33,6 +33,11 @@ enum unpack_trees_error_types {
3333
void setup_unpack_trees_porcelain(struct unpack_trees_options *opts,
3434
const char *cmd);
3535

36+
/*
37+
* Frees resources allocated by setup_unpack_trees_porcelain().
38+
*/
39+
void clear_unpack_trees_porcelain(struct unpack_trees_options *opts);
40+
3641
struct unpack_trees_options {
3742
unsigned int reset,
3843
merge,
@@ -57,6 +62,7 @@ struct unpack_trees_options {
5762
struct pathspec *pathspec;
5863
merge_fn_t fn;
5964
const char *msgs[NB_UNPACK_TREES_ERROR_TYPES];
65+
struct argv_array msgs_to_free;
6066
/*
6167
* Store error messages in an array, each case
6268
* corresponding to a error message type

0 commit comments

Comments
 (0)