Skip to content

Commit 3997614

Browse files
committed
Merge branch 'ps/leakfixes-more'
More memory leaks have been plugged. * ps/leakfixes-more: (29 commits) builtin/blame: fix leaking ignore revs files builtin/blame: fix leaking prefixed paths blame: fix leaking data for blame scoreboards line-range: plug leaking find functions merge: fix leaking merge bases builtin/merge: fix leaking `struct cmdnames` in `get_strategy()` sequencer: fix memory leaks in `make_script_with_merges()` builtin/clone: plug leaking HEAD ref in `wanted_peer_refs()` apply: fix leaking string in `match_fragment()` sequencer: fix leaking string buffer in `commit_staged_changes()` commit: fix leaking parents when calling `commit_tree_extended()` config: fix leaking "core.notesref" variable rerere: fix various trivial leaks builtin/stash: fix leak in `show_stash()` revision: free diff options builtin/log: fix leaking commit list in git-cherry(1) merge-recursive: fix memory leak when finalizing merge builtin/merge-recursive: fix leaking object ID bases builtin/difftool: plug memory leaks in `run_dir_diff()` object-name: free leaking object contexts ...
2 parents ecf7fc6 + fbf7a46 commit 3997614

File tree

130 files changed

+591
-272
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

130 files changed

+591
-272
lines changed

apply.c

+56-32
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ void clear_apply_state(struct apply_state *state)
137137
strset_clear(&state->removed_symlinks);
138138
strset_clear(&state->kept_symlinks);
139139
strbuf_release(&state->root);
140+
FREE_AND_NULL(state->fake_ancestor);
140141

141142
/* &state->fn_table is cleared at the end of apply_patch() */
142143
}
@@ -2495,18 +2496,21 @@ static int match_fragment(struct apply_state *state,
24952496
int match_beginning, int match_end)
24962497
{
24972498
int i;
2498-
char *fixed_buf, *buf, *orig, *target;
2499-
struct strbuf fixed;
2500-
size_t fixed_len, postlen;
2499+
const char *orig, *target;
2500+
struct strbuf fixed = STRBUF_INIT;
2501+
size_t postlen;
25012502
int preimage_limit;
2503+
int ret;
25022504

25032505
if (preimage->nr + current_lno <= img->nr) {
25042506
/*
25052507
* The hunk falls within the boundaries of img.
25062508
*/
25072509
preimage_limit = preimage->nr;
2508-
if (match_end && (preimage->nr + current_lno != img->nr))
2509-
return 0;
2510+
if (match_end && (preimage->nr + current_lno != img->nr)) {
2511+
ret = 0;
2512+
goto out;
2513+
}
25102514
} else if (state->ws_error_action == correct_ws_error &&
25112515
(ws_rule & WS_BLANK_AT_EOF)) {
25122516
/*
@@ -2523,17 +2527,23 @@ static int match_fragment(struct apply_state *state,
25232527
* we are not removing blanks at the end, so we
25242528
* should reject the hunk at this position.
25252529
*/
2526-
return 0;
2530+
ret = 0;
2531+
goto out;
25272532
}
25282533

2529-
if (match_beginning && current_lno)
2530-
return 0;
2534+
if (match_beginning && current_lno) {
2535+
ret = 0;
2536+
goto out;
2537+
}
25312538

25322539
/* Quick hash check */
2533-
for (i = 0; i < preimage_limit; i++)
2540+
for (i = 0; i < preimage_limit; i++) {
25342541
if ((img->line[current_lno + i].flag & LINE_PATCHED) ||
2535-
(preimage->line[i].hash != img->line[current_lno + i].hash))
2536-
return 0;
2542+
(preimage->line[i].hash != img->line[current_lno + i].hash)) {
2543+
ret = 0;
2544+
goto out;
2545+
}
2546+
}
25372547

25382548
if (preimage_limit == preimage->nr) {
25392549
/*
@@ -2546,8 +2556,10 @@ static int match_fragment(struct apply_state *state,
25462556
if ((match_end
25472557
? (current + preimage->len == img->len)
25482558
: (current + preimage->len <= img->len)) &&
2549-
!memcmp(img->buf + current, preimage->buf, preimage->len))
2550-
return 1;
2559+
!memcmp(img->buf + current, preimage->buf, preimage->len)) {
2560+
ret = 1;
2561+
goto out;
2562+
}
25512563
} else {
25522564
/*
25532565
* The preimage extends beyond the end of img, so
@@ -2556,7 +2568,7 @@ static int match_fragment(struct apply_state *state,
25562568
* There must be one non-blank context line that match
25572569
* a line before the end of img.
25582570
*/
2559-
char *buf_end;
2571+
const char *buf, *buf_end;
25602572

25612573
buf = preimage->buf;
25622574
buf_end = buf;
@@ -2566,21 +2578,27 @@ static int match_fragment(struct apply_state *state,
25662578
for ( ; buf < buf_end; buf++)
25672579
if (!isspace(*buf))
25682580
break;
2569-
if (buf == buf_end)
2570-
return 0;
2581+
if (buf == buf_end) {
2582+
ret = 0;
2583+
goto out;
2584+
}
25712585
}
25722586

25732587
/*
25742588
* No exact match. If we are ignoring whitespace, run a line-by-line
25752589
* fuzzy matching. We collect all the line length information because
25762590
* we need it to adjust whitespace if we match.
25772591
*/
2578-
if (state->ws_ignore_action == ignore_ws_change)
2579-
return line_by_line_fuzzy_match(img, preimage, postimage,
2580-
current, current_lno, preimage_limit);
2592+
if (state->ws_ignore_action == ignore_ws_change) {
2593+
ret = line_by_line_fuzzy_match(img, preimage, postimage,
2594+
current, current_lno, preimage_limit);
2595+
goto out;
2596+
}
25812597

2582-
if (state->ws_error_action != correct_ws_error)
2583-
return 0;
2598+
if (state->ws_error_action != correct_ws_error) {
2599+
ret = 0;
2600+
goto out;
2601+
}
25842602

25852603
/*
25862604
* The hunk does not apply byte-by-byte, but the hash says
@@ -2609,7 +2627,7 @@ static int match_fragment(struct apply_state *state,
26092627
* but in this loop we will only handle the part of the
26102628
* preimage that falls within the file.
26112629
*/
2612-
strbuf_init(&fixed, preimage->len + 1);
2630+
strbuf_grow(&fixed, preimage->len + 1);
26132631
orig = preimage->buf;
26142632
target = img->buf + current;
26152633
for (i = 0; i < preimage_limit; i++) {
@@ -2645,8 +2663,10 @@ static int match_fragment(struct apply_state *state,
26452663
postlen += tgtfix.len;
26462664

26472665
strbuf_release(&tgtfix);
2648-
if (!match)
2649-
goto unmatch_exit;
2666+
if (!match) {
2667+
ret = 0;
2668+
goto out;
2669+
}
26502670

26512671
orig += oldlen;
26522672
target += tgtlen;
@@ -2667,9 +2687,13 @@ static int match_fragment(struct apply_state *state,
26672687
/* Try fixing the line in the preimage */
26682688
ws_fix_copy(&fixed, orig, oldlen, ws_rule, NULL);
26692689

2670-
for (j = fixstart; j < fixed.len; j++)
2671-
if (!isspace(fixed.buf[j]))
2672-
goto unmatch_exit;
2690+
for (j = fixstart; j < fixed.len; j++) {
2691+
if (!isspace(fixed.buf[j])) {
2692+
ret = 0;
2693+
goto out;
2694+
}
2695+
}
2696+
26732697

26742698
orig += oldlen;
26752699
}
@@ -2679,16 +2703,16 @@ static int match_fragment(struct apply_state *state,
26792703
* has whitespace breakages unfixed, and fixing them makes the
26802704
* hunk match. Update the context lines in the postimage.
26812705
*/
2682-
fixed_buf = strbuf_detach(&fixed, &fixed_len);
26832706
if (postlen < postimage->len)
26842707
postlen = 0;
26852708
update_pre_post_images(preimage, postimage,
2686-
fixed_buf, fixed_len, postlen);
2687-
return 1;
2709+
fixed.buf, fixed.len, postlen);
26882710

2689-
unmatch_exit:
2711+
ret = 1;
2712+
2713+
out:
26902714
strbuf_release(&fixed);
2691-
return 0;
2715+
return ret;
26922716
}
26932717

26942718
static int find_pos(struct apply_state *state,

apply.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ struct apply_state {
5959
struct repository *repo;
6060
const char *index_file;
6161
enum apply_verbosity apply_verbosity;
62-
const char *fake_ancestor;
62+
char *fake_ancestor;
6363
const char *patch_input_file;
6464
int line_termination;
6565
struct strbuf root;

blame.c

+4
Original file line numberDiff line numberDiff line change
@@ -2930,6 +2930,10 @@ void setup_blame_bloom_data(struct blame_scoreboard *sb)
29302930

29312931
void cleanup_scoreboard(struct blame_scoreboard *sb)
29322932
{
2933+
free(sb->lineno);
2934+
clear_prio_queue(&sb->commits);
2935+
oidset_clear(&sb->ignore_list);
2936+
29332937
if (sb->bloom_data) {
29342938
int i;
29352939
for (i = 0; i < sb->bloom_data->nr; i++) {

builtin/am.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -1573,8 +1573,8 @@ static int build_fake_ancestor(const struct am_state *state, const char *index_f
15731573
*/
15741574
static int fall_back_threeway(const struct am_state *state, const char *index_path)
15751575
{
1576-
struct object_id orig_tree, their_tree, our_tree;
1577-
const struct object_id *bases[1] = { &orig_tree };
1576+
struct object_id their_tree, our_tree;
1577+
struct object_id bases[1] = { 0 };
15781578
struct merge_options o;
15791579
struct commit *result;
15801580
char *their_tree_name;
@@ -1588,7 +1588,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
15881588
discard_index(the_repository->index);
15891589
read_index_from(the_repository->index, index_path, get_git_dir());
15901590

1591-
if (write_index_as_tree(&orig_tree, the_repository->index, index_path, 0, NULL))
1591+
if (write_index_as_tree(&bases[0], the_repository->index, index_path, 0, NULL))
15921592
return error(_("Repository lacks necessary blobs to fall back on 3-way merge."));
15931593

15941594
say(state, stdout, _("Using index info to reconstruct a base tree..."));
@@ -1718,6 +1718,7 @@ static void do_commit(const struct am_state *state)
17181718

17191719
run_hooks("post-applypatch");
17201720

1721+
free_commit_list(parents);
17211722
strbuf_release(&sb);
17221723
}
17231724

builtin/archive.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
9090
N_("path to the remote git-upload-archive command")),
9191
OPT_END()
9292
};
93+
int ret;
9394

9495
argc = parse_options(argc, argv, prefix, local_opts, NULL,
9596
PARSE_OPT_KEEP_ALL);
@@ -104,6 +105,8 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
104105

105106
setvbuf(stderr, NULL, _IOLBF, BUFSIZ);
106107

107-
UNLEAK(output);
108-
return write_archive(argc, argv, prefix, the_repository, output, 0);
108+
ret = write_archive(argc, argv, prefix, the_repository, output, 0);
109+
110+
free(output);
111+
return ret;
109112
}

builtin/blame.c

+5-3
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ static int no_whole_file_rename;
6767
static int show_progress;
6868
static char repeated_meta_color[COLOR_MAXLEN];
6969
static int coloring_mode;
70-
static struct string_list ignore_revs_file_list = STRING_LIST_INIT_NODUP;
70+
static struct string_list ignore_revs_file_list = STRING_LIST_INIT_DUP;
7171
static int mark_unblamable_lines;
7272
static int mark_ignored_lines;
7373

@@ -687,7 +687,7 @@ static unsigned parse_score(const char *arg)
687687
return score;
688688
}
689689

690-
static const char *add_prefix(const char *prefix, const char *path)
690+
static char *add_prefix(const char *prefix, const char *path)
691691
{
692692
return prefix_path(prefix, prefix ? strlen(prefix) : 0, path);
693693
}
@@ -725,6 +725,7 @@ static int git_blame_config(const char *var, const char *value,
725725
if (ret)
726726
return ret;
727727
string_list_insert(&ignore_revs_file_list, str);
728+
free(str);
728729
return 0;
729730
}
730731
if (!strcmp(var, "blame.markunblamablelines")) {
@@ -866,7 +867,7 @@ static void build_ignorelist(struct blame_scoreboard *sb,
866867
int cmd_blame(int argc, const char **argv, const char *prefix)
867868
{
868869
struct rev_info revs;
869-
const char *path;
870+
char *path = NULL;
870871
struct blame_scoreboard sb;
871872
struct blame_origin *o;
872873
struct blame_entry *ent = NULL;
@@ -1227,6 +1228,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
12271228
}
12281229

12291230
cleanup:
1231+
free(path);
12301232
cleanup_scoreboard(&sb);
12311233
release_revisions(&revs);
12321234
return 0;

builtin/cat-file.c

+11-6
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
102102
enum object_type type;
103103
char *buf;
104104
unsigned long size;
105-
struct object_context obj_context;
105+
struct object_context obj_context = {0};
106106
struct object_info oi = OBJECT_INFO_INIT;
107107
struct strbuf sb = STRBUF_INIT;
108108
unsigned flags = OBJECT_INFO_LOOKUP_REPLACE;
@@ -163,7 +163,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
163163
goto cleanup;
164164

165165
case 'e':
166-
return !repo_has_object_file(the_repository, &oid);
166+
ret = !repo_has_object_file(the_repository, &oid);
167+
goto cleanup;
167168

168169
case 'w':
169170

@@ -268,7 +269,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
268269
ret = 0;
269270
cleanup:
270271
free(buf);
271-
free(obj_context.path);
272+
object_context_release(&obj_context);
272273
return ret;
273274
}
274275

@@ -520,7 +521,7 @@ static void batch_one_object(const char *obj_name,
520521
struct batch_options *opt,
521522
struct expand_data *data)
522523
{
523-
struct object_context ctx;
524+
struct object_context ctx = {0};
524525
int flags =
525526
GET_OID_HASH_ANY |
526527
(opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0);
@@ -557,18 +558,22 @@ static void batch_one_object(const char *obj_name,
557558
break;
558559
}
559560
fflush(stdout);
560-
return;
561+
562+
goto out;
561563
}
562564

563565
if (ctx.mode == 0) {
564566
printf("symlink %"PRIuMAX"%c%s%c",
565567
(uintmax_t)ctx.symlink_path.len,
566568
opt->output_delim, ctx.symlink_path.buf, opt->output_delim);
567569
fflush(stdout);
568-
return;
570+
goto out;
569571
}
570572

571573
batch_object_write(obj_name, scratch, opt, data, NULL, 0);
574+
575+
out:
576+
object_context_release(&ctx);
572577
}
573578

574579
struct object_cb_data {

builtin/clone.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -533,7 +533,8 @@ static struct ref *wanted_peer_refs(const struct ref *refs,
533533
if (!option_branch)
534534
remote_head = guess_remote_head(head, refs, 0);
535535
else {
536-
local_refs = NULL;
536+
free_one_ref(head);
537+
local_refs = head = NULL;
537538
tail = &local_refs;
538539
remote_head = copy_ref(find_remote_branch(refs, option_branch));
539540
}

builtin/commit-tree.c

+8-3
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
111111
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
112112
OPT_END()
113113
};
114+
int ret;
114115

115116
git_config(git_default_config, NULL);
116117

@@ -132,11 +133,15 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
132133

133134
if (commit_tree(buffer.buf, buffer.len, &tree_oid, parents, &commit_oid,
134135
NULL, sign_commit)) {
135-
strbuf_release(&buffer);
136-
return 1;
136+
ret = 1;
137+
goto out;
137138
}
138139

139140
printf("%s\n", oid_to_hex(&commit_oid));
141+
ret = 0;
142+
143+
out:
144+
free_commit_list(parents);
140145
strbuf_release(&buffer);
141-
return 0;
146+
return ret;
142147
}

0 commit comments

Comments
 (0)