Skip to content

Commit 2664f2a

Browse files
committed
Merge branch 'ps/leakfixes-part-9' into ps/leakfixes-part-10
* ps/leakfixes-part-9: (22 commits) list-objects-filter-options: work around reported leak on error builtin/merge: release output buffer after performing merge dir: fix leak when parsing "status.showUntrackedFiles" t/helper: fix leaking buffer in "dump-untracked-cache" t/helper: stop re-initialization of `the_repository` sparse-index: correctly free EWAH contents dir: release untracked cache data combine-diff: fix leaking lost lines builtin/tag: fix leaking key ID on failure to sign transport-helper: fix leaking import/export marks builtin/commit: fix leaking cleanup config trailer: fix leaking strbufs when formatting trailers trailer: fix leaking trailer values builtin/commit: fix leaking change data contents upload-pack: fix leaking URI protocols pretty: clear signature check diff-lib: fix leaking diffopts in `do_diff_cache()` revision: fix leaking bloom filters builtin/grep: fix leak with `--max-count=0` grep: fix leak in `grep_splice_or()` ...
2 parents 8f8d6ee + c810549 commit 2664f2a

38 files changed

+115
-35
lines changed

builtin/commit.c

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ static struct strvec trailer_args = STRVEC_INIT;
135135
* is specified explicitly.
136136
*/
137137
static enum commit_msg_cleanup_mode cleanup_mode;
138-
static char *cleanup_arg;
138+
static char *cleanup_config;
139139

140140
static enum commit_whence whence;
141141
static int use_editor = 1, include_status = 1;
@@ -728,6 +728,13 @@ static void prepare_amend_commit(struct commit *commit, struct strbuf *sb,
728728
repo_unuse_commit_buffer(the_repository, commit, buffer);
729729
}
730730

731+
static void change_data_free(void *util, const char *str UNUSED)
732+
{
733+
struct wt_status_change_data *d = util;
734+
free(d->rename_source);
735+
free(d);
736+
}
737+
731738
static int prepare_to_commit(const char *index_file, const char *prefix,
732739
struct commit *current_head,
733740
struct wt_status *s,
@@ -991,7 +998,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
991998
s->use_color = 0;
992999
committable = run_status(s->fp, index_file, prefix, 1, s);
9931000
s->use_color = saved_color_setting;
994-
string_list_clear(&s->change, 1);
1001+
string_list_clear_func(&s->change, change_data_free);
9951002
} else {
9961003
struct object_id oid;
9971004
const char *parent = "HEAD";
@@ -1380,8 +1387,6 @@ static int parse_and_validate_options(int argc, const char *argv[],
13801387
if (0 <= edit_flag)
13811388
use_editor = edit_flag;
13821389

1383-
cleanup_mode = get_cleanup_mode(cleanup_arg, use_editor);
1384-
13851390
handle_untracked_files_arg(s);
13861391

13871392
if (all && argc > 0)
@@ -1629,8 +1634,10 @@ static int git_commit_config(const char *k, const char *v,
16291634
include_status = git_config_bool(k, v);
16301635
return 0;
16311636
}
1632-
if (!strcmp(k, "commit.cleanup"))
1633-
return git_config_string(&cleanup_arg, k, v);
1637+
if (!strcmp(k, "commit.cleanup")) {
1638+
FREE_AND_NULL(cleanup_config);
1639+
return git_config_string(&cleanup_config, k, v);
1640+
}
16341641
if (!strcmp(k, "commit.gpgsign")) {
16351642
sign_commit = git_config_bool(k, v) ? "" : NULL;
16361643
return 0;
@@ -1651,6 +1658,7 @@ int cmd_commit(int argc,
16511658
struct repository *repo UNUSED)
16521659
{
16531660
static struct wt_status s;
1661+
static const char *cleanup_arg = NULL;
16541662
static struct option builtin_commit_options[] = {
16551663
OPT__QUIET(&quiet, N_("suppress summary after successful commit")),
16561664
OPT__VERBOSE(&verbose, N_("show diff in commit message template")),
@@ -1750,6 +1758,12 @@ int cmd_commit(int argc,
17501758
if (verbose == -1)
17511759
verbose = (config_commit_verbose < 0) ? 0 : config_commit_verbose;
17521760

1761+
if (cleanup_arg) {
1762+
free(cleanup_config);
1763+
cleanup_config = xstrdup(cleanup_arg);
1764+
}
1765+
cleanup_mode = get_cleanup_mode(cleanup_config, use_editor);
1766+
17531767
if (dry_run)
17541768
return dry_run_commit(argv, prefix, current_head, &s);
17551769
index_file = prepare_index(argv, prefix, current_head, 0);

builtin/grep.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -906,6 +906,7 @@ int cmd_grep(int argc,
906906
int dummy;
907907
int use_index = 1;
908908
int allow_revs;
909+
int ret;
909910

910911
struct option options[] = {
911912
OPT_BOOL(0, "cached", &cached,
@@ -1172,8 +1173,10 @@ int cmd_grep(int argc,
11721173
* Optimize out the case where the amount of matches is limited to zero.
11731174
* We do this to keep results consistent with GNU grep(1).
11741175
*/
1175-
if (opt.max_count == 0)
1176-
return 1;
1176+
if (opt.max_count == 0) {
1177+
ret = 1;
1178+
goto out;
1179+
}
11771180

11781181
if (show_in_pager) {
11791182
if (num_threads > 1)
@@ -1267,10 +1270,14 @@ int cmd_grep(int argc,
12671270
hit |= wait_all();
12681271
if (hit && show_in_pager)
12691272
run_pager(&opt, prefix);
1273+
1274+
ret = !hit;
1275+
1276+
out:
12701277
clear_pathspec(&pathspec);
12711278
string_list_clear(&path_list, 0);
12721279
free_grep_patterns(&opt);
12731280
object_array_clear(&list);
12741281
free_repos();
1275-
return !hit;
1282+
return ret;
12761283
}

builtin/ls-remote.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ int cmd_ls_remote(int argc,
166166
status = 0; /* we found something */
167167
}
168168

169+
string_list_clear(&server_options, 0);
169170
ref_sorting_release(sorting);
170171
ref_array_clear(&ref_array);
171172
if (transport_disconnect(transport))

builtin/merge.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -754,6 +754,7 @@ static int try_merge_strategy(const char *strategy, struct commit_list *common,
754754
clean = merge_recursive(&o, head, remoteheads->item,
755755
reversed, &result);
756756
free_commit_list(reversed);
757+
strbuf_release(&o.obuf);
757758

758759
if (clean < 0) {
759760
rollback_lock_file(&lock);

builtin/tag.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ static int do_sign(struct strbuf *buffer, struct object_id **compat_oid,
164164
int ret = -1;
165165

166166
if (sign_buffer(buffer, &sig, keyid))
167-
return -1;
167+
goto out;
168168

169169
if (compat) {
170170
const struct git_hash_algo *algo = the_repository->hash_algo;

combine-diff.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1185,7 +1185,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
11851185
result_file.ptr = result;
11861186
result_file.size = result_size;
11871187

1188-
/* Even p_lno[cnt+1] is valid -- that is for the end line number
1188+
/*
1189+
* Even p_lno[cnt+1] is valid -- that is for the end line number
11891190
* for deletion hunk at the end.
11901191
*/
11911192
CALLOC_ARRAY(sline[0].p_lno, st_mult(st_add(cnt, 2), num_parent));
@@ -1220,7 +1221,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
12201221
}
12211222
free(result);
12221223

1223-
for (lno = 0; lno < cnt; lno++) {
1224+
for (lno = 0; lno < cnt + 2; lno++) {
12241225
if (sline[lno].lost) {
12251226
struct lline *ll = sline[lno].lost;
12261227
while (ll) {

diff-lib.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -661,6 +661,7 @@ int do_diff_cache(const struct object_id *tree_oid, struct diff_options *opt)
661661

662662
repo_init_revisions(opt->repo, &revs, NULL);
663663
copy_pathspec(&revs.prune_data, &opt->pathspec);
664+
diff_free(&revs.diffopt);
664665
revs.diffopt = *opt;
665666
revs.diffopt.no_free = 1;
666667

dir.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,8 @@ static void do_invalidate_gitignore(struct untracked_cache_dir *dir)
10561056
{
10571057
int i;
10581058
dir->valid = 0;
1059+
for (size_t i = 0; i < dir->untracked_nr; i++)
1060+
free(dir->untracked[i]);
10591061
dir->untracked_nr = 0;
10601062
for (i = 0; i < dir->dirs_nr; i++)
10611063
do_invalidate_gitignore(dir->dirs[i]);
@@ -1083,6 +1085,8 @@ static void invalidate_directory(struct untracked_cache *uc,
10831085
uc->dir_invalidated++;
10841086

10851087
dir->valid = 0;
1088+
for (size_t i = 0; i < dir->untracked_nr; i++)
1089+
free(dir->untracked[i]);
10861090
dir->untracked_nr = 0;
10871091
for (i = 0; i < dir->dirs_nr; i++)
10881092
dir->dirs[i]->recurse = 0;
@@ -2868,14 +2872,14 @@ static void set_untracked_ident(struct untracked_cache *uc)
28682872
static unsigned new_untracked_cache_flags(struct index_state *istate)
28692873
{
28702874
struct repository *repo = istate->repo;
2871-
char *val;
2875+
const char *val;
28722876

28732877
/*
28742878
* This logic is coordinated with the setting of these flags in
28752879
* wt-status.c#wt_status_collect_untracked(), and the evaluation
28762880
* of the config setting in commit.c#git_status_config()
28772881
*/
2878-
if (!repo_config_get_string(repo, "status.showuntrackedfiles", &val) &&
2882+
if (!repo_config_get_string_tmp(repo, "status.showuntrackedfiles", &val) &&
28792883
!strcmp(val, "all"))
28802884
return 0;
28812885

@@ -3573,6 +3577,8 @@ static void write_one_dir(struct untracked_cache_dir *untracked,
35733577
* for safety..
35743578
*/
35753579
if (!untracked->valid) {
3580+
for (size_t i = 0; i < untracked->untracked_nr; i++)
3581+
free(untracked->untracked[i]);
35763582
untracked->untracked_nr = 0;
35773583
untracked->check_only = 0;
35783584
}
@@ -3905,6 +3911,8 @@ static void invalidate_one_directory(struct untracked_cache *uc,
39053911
{
39063912
uc->dir_invalidated++;
39073913
ucd->valid = 0;
3914+
for (size_t i = 0; i < ucd->untracked_nr; i++)
3915+
free(ucd->untracked[i]);
39083916
ucd->untracked_nr = 0;
39093917
}
39103918

grep.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -756,6 +756,7 @@ static struct grep_expr *grep_splice_or(struct grep_expr *x, struct grep_expr *y
756756
assert(x->node == GREP_NODE_OR);
757757
if (x->u.binary.right &&
758758
x->u.binary.right->node == GREP_NODE_TRUE) {
759+
free(x->u.binary.right);
759760
x->u.binary.right = y;
760761
break;
761762
}

list-objects-filter-options.c

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -252,16 +252,14 @@ void parse_list_objects_filter(
252252
const char *arg)
253253
{
254254
struct strbuf errbuf = STRBUF_INIT;
255-
int parse_error;
256255

257256
if (!filter_options->filter_spec.buf)
258257
BUG("filter_options not properly initialized");
259258

260259
if (!filter_options->choice) {
260+
if (gently_parse_list_objects_filter(filter_options, arg, &errbuf))
261+
die("%s", errbuf.buf);
261262
strbuf_addstr(&filter_options->filter_spec, arg);
262-
263-
parse_error = gently_parse_list_objects_filter(
264-
filter_options, arg, &errbuf);
265263
} else {
266264
struct list_objects_filter_options *sub;
267265

@@ -271,18 +269,17 @@ void parse_list_objects_filter(
271269
*/
272270
transform_to_combine_type(filter_options);
273271

274-
strbuf_addch(&filter_options->filter_spec, '+');
275-
filter_spec_append_urlencode(filter_options, arg);
276272
ALLOC_GROW_BY(filter_options->sub, filter_options->sub_nr, 1,
277273
filter_options->sub_alloc);
278274
sub = &filter_options->sub[filter_options->sub_nr - 1];
279275

280276
list_objects_filter_init(sub);
281-
parse_error = gently_parse_list_objects_filter(sub, arg,
282-
&errbuf);
277+
if (gently_parse_list_objects_filter(sub, arg, &errbuf))
278+
die("%s", errbuf.buf);
279+
280+
strbuf_addch(&filter_options->filter_spec, '+');
281+
filter_spec_append_urlencode(filter_options, arg);
283282
}
284-
if (parse_error)
285-
die("%s", errbuf.buf);
286283
}
287284

288285
int opt_parse_list_objects_filter(const struct option *opt,

0 commit comments

Comments
 (0)