Skip to content

Commit 1b6b2bf

Browse files
committed
Merge branch 'ps/leakfixes-part-4'
More leak fixes. * ps/leakfixes-part-4: (22 commits) builtin/diff: free symmetric diff members diff: free state populated via options builtin/log: fix leak when showing converted blob contents userdiff: fix leaking memory for configured diff drivers builtin/format-patch: fix various trivial memory leaks diff: fix leak when parsing invalid ignore regex option unpack-trees: clear index when not propagating it sequencer: release todo list on error paths merge-ort: unconditionally release attributes index builtin/fast-export: plug leaking tag names builtin/fast-export: fix leaking diff options builtin/fast-import: plug trivial memory leaks builtin/notes: fix leaking `struct notes_tree` when merging notes builtin/rebase: fix leaking `commit.gpgsign` value config: fix leaking comment character config submodule-config: fix leaking name entry when traversing submodules read-cache: fix leaking hashfile when writing index fails bulk-checkin: fix leaking state TODO object-name: fix leaking symlink paths in object context object-file: fix memory leak when reading corrupted headers ...
2 parents 3a7362e + 77d4b3d commit 1b6b2bf

Some content is hidden

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

58 files changed

+265
-142
lines changed

builtin/commit.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -684,7 +684,9 @@ static void adjust_comment_line_char(const struct strbuf *sb)
684684
const char *p;
685685

686686
if (!memchr(sb->buf, candidates[0], sb->len)) {
687-
comment_line_str = xstrfmt("%c", candidates[0]);
687+
free(comment_line_str_to_free);
688+
comment_line_str = comment_line_str_to_free =
689+
xstrfmt("%c", candidates[0]);
688690
return;
689691
}
690692

@@ -705,7 +707,8 @@ static void adjust_comment_line_char(const struct strbuf *sb)
705707
if (!*p)
706708
die(_("unable to select a comment character that is not used\n"
707709
"in the current commit message"));
708-
comment_line_str = xstrfmt("%c", *p);
710+
free(comment_line_str_to_free);
711+
comment_line_str = comment_line_str_to_free = xstrfmt("%c", *p);
709712
}
710713

711714
static void prepare_amend_commit(struct commit *commit, struct strbuf *sb,

builtin/diff.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,11 @@ static void symdiff_prepare(struct rev_info *rev, struct symdiff *sym)
388388
sym->skip = map;
389389
}
390390

391+
static void symdiff_release(struct symdiff *sdiff)
392+
{
393+
bitmap_free(sdiff->skip);
394+
}
395+
391396
int cmd_diff(int argc, const char **argv, const char *prefix)
392397
{
393398
int i;
@@ -619,6 +624,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
619624
refresh_index_quietly();
620625
release_revisions(&rev);
621626
object_array_clear(&ent);
627+
symdiff_release(&sdiff);
622628
UNLEAK(blob);
623629
return result;
624630
}

builtin/fast-export.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ static int full_tree;
4242
static int reference_excluded_commits;
4343
static int show_original_ids;
4444
static int mark_tags;
45-
static struct string_list extra_refs = STRING_LIST_INIT_NODUP;
46-
static struct string_list tag_refs = STRING_LIST_INIT_NODUP;
45+
static struct string_list extra_refs = STRING_LIST_INIT_DUP;
46+
static struct string_list tag_refs = STRING_LIST_INIT_DUP;
4747
static struct refspec refspecs = REFSPEC_INIT_FETCH;
4848
static int anonymize;
4949
static struct hashmap anonymized_seeds;
@@ -901,7 +901,7 @@ static void handle_tag(const char *name, struct tag *tag)
901901
free(buf);
902902
}
903903

904-
static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name)
904+
static struct commit *get_commit(struct rev_cmdline_entry *e, const char *full_name)
905905
{
906906
switch (e->item->type) {
907907
case OBJ_COMMIT:
@@ -932,14 +932,16 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
932932
struct rev_cmdline_entry *e = info->rev + i;
933933
struct object_id oid;
934934
struct commit *commit;
935-
char *full_name;
935+
char *full_name = NULL;
936936

937937
if (e->flags & UNINTERESTING)
938938
continue;
939939

940940
if (repo_dwim_ref(the_repository, e->name, strlen(e->name),
941-
&oid, &full_name, 0) != 1)
941+
&oid, &full_name, 0) != 1) {
942+
free(full_name);
942943
continue;
944+
}
943945

944946
if (refspecs.nr) {
945947
char *private;
@@ -955,6 +957,7 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
955957
warning("%s: Unexpected object of type %s, skipping.",
956958
e->name,
957959
type_name(e->item->type));
960+
free(full_name);
958961
continue;
959962
}
960963

@@ -963,10 +966,12 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
963966
break;
964967
case OBJ_BLOB:
965968
export_blob(&commit->object.oid);
969+
free(full_name);
966970
continue;
967971
default: /* OBJ_TAG (nested tags) is already handled */
968972
warning("Tag points to object of unexpected type %s, skipping.",
969973
type_name(commit->object.type));
974+
free(full_name);
970975
continue;
971976
}
972977

@@ -979,6 +984,8 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)
979984

980985
if (!*revision_sources_at(&revision_sources, commit))
981986
*revision_sources_at(&revision_sources, commit) = full_name;
987+
else
988+
free(full_name);
982989
}
983990

984991
string_list_sort(&extra_refs);
@@ -1278,9 +1285,11 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
12781285
revs.diffopt.format_callback = show_filemodify;
12791286
revs.diffopt.format_callback_data = &paths_of_changed_objects;
12801287
revs.diffopt.flags.recursive = 1;
1288+
12811289
revs.diffopt.no_free = 1;
12821290
while ((commit = get_revision(&revs)))
12831291
handle_commit(commit, &revs, &paths_of_changed_objects);
1292+
revs.diffopt.no_free = 0;
12841293

12851294
handle_tags_and_duplicates(&extra_refs);
12861295
handle_tags_and_duplicates(&tag_refs);

builtin/fast-import.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -206,8 +206,8 @@ static unsigned int object_entry_alloc = 5000;
206206
static struct object_entry_pool *blocks;
207207
static struct hashmap object_table;
208208
static struct mark_set *marks;
209-
static const char *export_marks_file;
210-
static const char *import_marks_file;
209+
static char *export_marks_file;
210+
static char *import_marks_file;
211211
static int import_marks_file_from_stream;
212212
static int import_marks_file_ignore_missing;
213213
static int import_marks_file_done;
@@ -3274,6 +3274,7 @@ static void option_import_marks(const char *marks,
32743274
read_marks();
32753275
}
32763276

3277+
free(import_marks_file);
32773278
import_marks_file = make_fast_import_path(marks);
32783279
import_marks_file_from_stream = from_stream;
32793280
import_marks_file_ignore_missing = ignore_missing;
@@ -3316,6 +3317,7 @@ static void option_active_branches(const char *branches)
33163317

33173318
static void option_export_marks(const char *marks)
33183319
{
3320+
free(export_marks_file);
33193321
export_marks_file = make_fast_import_path(marks);
33203322
}
33213323

@@ -3357,6 +3359,8 @@ static void option_rewrite_submodules(const char *arg, struct string_list *list)
33573359
free(f);
33583360

33593361
string_list_insert(list, s)->util = ms;
3362+
3363+
free(s);
33603364
}
33613365

33623366
static int parse_one_option(const char *option)

builtin/log.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,7 @@ static int show_blob_object(const struct object_id *oid, struct rev_info *rev, c
707707

708708
write_or_die(1, buf, size);
709709
object_context_release(&obj_context);
710+
free(buf);
710711
return 0;
711712
}
712713

@@ -1827,12 +1828,14 @@ static struct commit *get_base_commit(const struct format_config *cfg,
18271828
if (die_on_failure) {
18281829
die(_("failed to find exact merge base"));
18291830
} else {
1831+
free_commit_list(merge_base);
18301832
free(rev);
18311833
return NULL;
18321834
}
18331835
}
18341836

18351837
rev[i] = merge_base->item;
1838+
free_commit_list(merge_base);
18361839
}
18371840

18381841
if (rev_nr % 2)
@@ -2023,6 +2026,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
20232026
const char *rfc = NULL;
20242027
int creation_factor = -1;
20252028
const char *signature = git_version_string;
2029+
char *signature_to_free = NULL;
20262030
char *signature_file_arg = NULL;
20272031
struct keep_callback_data keep_callback_data = {
20282032
.cfg = &cfg,
@@ -2443,7 +2447,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
24432447

24442448
if (strbuf_read_file(&buf, signature_file, 128) < 0)
24452449
die_errno(_("unable to read signature file '%s'"), signature_file);
2446-
signature = strbuf_detach(&buf, NULL);
2450+
signature = signature_to_free = strbuf_detach(&buf, NULL);
24472451
} else if (cfg.signature) {
24482452
signature = cfg.signature;
24492453
}
@@ -2548,12 +2552,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
25482552
else
25492553
print_signature(signature, rev.diffopt.file);
25502554
}
2551-
if (output_directory)
2555+
if (output_directory) {
25522556
fclose(rev.diffopt.file);
2557+
rev.diffopt.file = NULL;
2558+
}
25532559
}
25542560
stop_progress(&progress);
25552561
free(list);
2556-
free(branch_name);
25572562
if (ignore_if_in_upstream)
25582563
free_patch_ids(&ids);
25592564

@@ -2565,11 +2570,14 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix)
25652570
strbuf_release(&rdiff_title);
25662571
free(description_file);
25672572
free(signature_file_arg);
2573+
free(signature_to_free);
2574+
free(branch_name);
25682575
free(to_free);
25692576
free(rev.message_id);
25702577
if (rev.ref_message_ids)
25712578
string_list_clear(rev.ref_message_ids, 0);
25722579
free(rev.ref_message_ids);
2580+
rev.diffopt.no_free = 0;
25732581
release_revisions(&rev);
25742582
format_config_release(&cfg);
25752583
return 0;

builtin/notes.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ static int merge_commit(struct notes_merge_options *o)
805805
{
806806
struct strbuf msg = STRBUF_INIT;
807807
struct object_id oid, parent_oid;
808-
struct notes_tree *t;
808+
struct notes_tree t = {0};
809809
struct commit *partial;
810810
struct pretty_print_context pretty_ctx;
811811
void *local_ref_to_free;
@@ -828,16 +828,15 @@ static int merge_commit(struct notes_merge_options *o)
828828
else
829829
oidclr(&parent_oid, the_repository->hash_algo);
830830

831-
CALLOC_ARRAY(t, 1);
832-
init_notes(t, "NOTES_MERGE_PARTIAL", combine_notes_overwrite, 0);
831+
init_notes(&t, "NOTES_MERGE_PARTIAL", combine_notes_overwrite, 0);
833832

834833
o->local_ref = local_ref_to_free =
835834
refs_resolve_refdup(get_main_ref_store(the_repository),
836835
"NOTES_MERGE_REF", 0, &oid, NULL);
837836
if (!o->local_ref)
838837
die(_("failed to resolve NOTES_MERGE_REF"));
839838

840-
if (notes_merge_commit(o, t, partial, &oid))
839+
if (notes_merge_commit(o, &t, partial, &oid))
841840
die(_("failed to finalize notes merge"));
842841

843842
/* Reuse existing commit message in reflog message */
@@ -851,7 +850,7 @@ static int merge_commit(struct notes_merge_options *o)
851850
is_null_oid(&parent_oid) ? NULL : &parent_oid,
852851
0, UPDATE_REFS_DIE_ON_ERR);
853852

854-
free_notes(t);
853+
free_notes(&t);
855854
strbuf_release(&msg);
856855
ret = merge_abort(o);
857856
free(local_ref_to_free);

builtin/rebase.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,7 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts)
186186
replay.committer_date_is_author_date =
187187
opts->committer_date_is_author_date;
188188
replay.ignore_date = opts->ignore_date;
189+
free(replay.gpg_sign);
189190
replay.gpg_sign = xstrdup_or_null(opts->gpg_sign_opt);
190191
replay.reflog_action = xstrdup(opts->reflog_action);
191192
if (opts->strategy)

bulk-checkin.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ static void flush_bulk_checkin_packfile(struct bulk_checkin_packfile *state)
6161

6262
if (state->nr_written == 0) {
6363
close(state->f->fd);
64+
free_hashfile(state->f);
6465
unlink(state->pack_tmp_name);
6566
goto clear_exit;
6667
} else if (state->nr_written == 1) {
@@ -83,6 +84,7 @@ static void flush_bulk_checkin_packfile(struct bulk_checkin_packfile *state)
8384
free(state->written[i]);
8485

8586
clear_exit:
87+
free(state->pack_tmp_name);
8688
free(state->written);
8789
memset(state, 0, sizeof(*state));
8890

config.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1596,7 +1596,8 @@ static int git_default_core_config(const char *var, const char *value,
15961596
else if (value[0]) {
15971597
if (strchr(value, '\n'))
15981598
return error(_("%s cannot contain newline"), var);
1599-
comment_line_str = xstrdup(value);
1599+
comment_line_str = value;
1600+
FREE_AND_NULL(comment_line_str_to_free);
16001601
auto_comment_line_char = 0;
16011602
} else
16021603
return error(_("%s must have at least one character"), var);

csum-file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ void hashflush(struct hashfile *f)
5656
}
5757
}
5858

59-
static void free_hashfile(struct hashfile *f)
59+
void free_hashfile(struct hashfile *f)
6060
{
6161
free(f->buffer);
6262
free(f->check_buffer);

0 commit comments

Comments
 (0)