Skip to content

Commit 60c778d

Browse files
committed
Merge branch 'ps/leakfixes-part-10' into rj/strvec-splice-fix
* ps/leakfixes-part-10: (49 commits) t: remove TEST_PASSES_SANITIZE_LEAK annotations test-lib: unconditionally enable leak checking t: remove unneeded !SANITIZE_LEAK prerequisites t: mark some tests as leak free t5601: work around leak sanitizer issue git-compat-util: drop now-unused `UNLEAK()` macro global: drop `UNLEAK()` annotation t/helper: fix leaking commit graph in "read-graph" subcommand builtin/branch: fix leaking sorting options builtin/init-db: fix leaking directory paths builtin/help: fix leaks in `check_git_cmd()` help: fix leaking return value from `help_unknown_cmd()` help: fix leaking `struct cmdnames` help: refactor to not use globals for reading config builtin/sparse-checkout: fix leaking sanitized patterns split-index: fix memory leak in `move_cache_to_base_index()` git: refactor builtin handling to use a `struct strvec` git: refactor alias handling to use a `struct strvec` strvec: introduce new `strvec_splice()` function line-log: fix leak when rewriting commit parents ...
2 parents 8f8d6ee + fc1ddf4 commit 60c778d

File tree

949 files changed

+457
-1265
lines changed

Some content is hidden

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

949 files changed

+457
-1265
lines changed

bisect.c

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ static struct oid_array skipped_revs;
2828

2929
static struct object_id *current_bad_oid;
3030

31-
static const char *term_bad;
32-
static const char *term_good;
31+
static char *term_bad;
32+
static char *term_good;
3333

3434
/* Remember to update object flag allocation in object.h */
3535
#define COUNTED (1u<<16)
@@ -442,9 +442,12 @@ void find_bisection(struct commit_list **commit_list, int *reaches,
442442
best->next = NULL;
443443
}
444444
*reaches = weight(best);
445+
} else {
446+
free_commit_list(*commit_list);
445447
}
446-
free(weights);
447448
*commit_list = best;
449+
450+
free(weights);
448451
clear_commit_weight(&commit_weight);
449452
}
450453

@@ -456,6 +459,7 @@ static int register_ref(const char *refname, const char *referent UNUSED, const
456459
strbuf_addstr(&good_prefix, "-");
457460

458461
if (!strcmp(refname, term_bad)) {
462+
free(current_bad_oid);
459463
current_bad_oid = xmalloc(sizeof(*current_bad_oid));
460464
oidcpy(current_bad_oid, oid);
461465
} else if (starts_with(refname, good_prefix.buf)) {
@@ -556,8 +560,11 @@ struct commit_list *filter_skipped(struct commit_list *list,
556560
tried = &list->next;
557561
} else {
558562
if (!show_all) {
559-
if (!skipped_first || !*skipped_first)
563+
if (!skipped_first || !*skipped_first) {
564+
free_commit_list(next);
565+
free_commit_list(filtered);
560566
return list;
567+
}
561568
} else if (skipped_first && !*skipped_first) {
562569
/* This means we know it's not skipped */
563570
*skipped_first = -1;
@@ -613,7 +620,7 @@ static int sqrti(int val)
613620

614621
static struct commit_list *skip_away(struct commit_list *list, int count)
615622
{
616-
struct commit_list *cur, *previous;
623+
struct commit_list *cur, *previous, *result = list;
617624
int prn, index, i;
618625

619626
prn = get_prn(count);
@@ -625,15 +632,23 @@ static struct commit_list *skip_away(struct commit_list *list, int count)
625632
for (i = 0; cur; cur = cur->next, i++) {
626633
if (i == index) {
627634
if (!oideq(&cur->item->object.oid, current_bad_oid))
628-
return cur;
629-
if (previous)
630-
return previous;
631-
return list;
635+
result = cur;
636+
else if (previous)
637+
result = previous;
638+
else
639+
result = list;
640+
break;
632641
}
633642
previous = cur;
634643
}
635644

636-
return list;
645+
for (cur = list; cur != result; ) {
646+
struct commit_list *next = cur->next;
647+
free(cur);
648+
cur = next;
649+
}
650+
651+
return result;
637652
}
638653

639654
static struct commit_list *managed_skipped(struct commit_list *list,
@@ -801,6 +816,8 @@ static enum bisect_error handle_bad_merge_base(void)
801816
"between %s and [%s].\n"),
802817
bad_hex, term_bad, term_good, bad_hex, good_hex);
803818
}
819+
820+
free(good_hex);
804821
return BISECT_MERGE_BASE_CHECK;
805822
}
806823

@@ -848,8 +865,8 @@ static enum bisect_error check_merge_bases(int rev_nr, struct commit **rev, int
848865
rev + 1, &result) < 0)
849866
exit(128);
850867

851-
for (; result; result = result->next) {
852-
const struct object_id *mb = &result->item->object.oid;
868+
for (struct commit_list *l = result; l; l = l->next) {
869+
const struct object_id *mb = &l->item->object.oid;
853870
if (oideq(mb, current_bad_oid)) {
854871
res = handle_bad_merge_base();
855872
break;
@@ -985,24 +1002,28 @@ static void show_commit(struct commit *commit)
9851002
* We read them and store them to adapt the messages accordingly.
9861003
* Default is bad/good.
9871004
*/
988-
void read_bisect_terms(const char **read_bad, const char **read_good)
1005+
void read_bisect_terms(char **read_bad, char **read_good)
9891006
{
9901007
struct strbuf str = STRBUF_INIT;
9911008
const char *filename = git_path_bisect_terms();
9921009
FILE *fp = fopen(filename, "r");
9931010

9941011
if (!fp) {
9951012
if (errno == ENOENT) {
996-
*read_bad = "bad";
997-
*read_good = "good";
1013+
free(*read_bad);
1014+
*read_bad = xstrdup("bad");
1015+
free(*read_good);
1016+
*read_good = xstrdup("good");
9981017
return;
9991018
} else {
10001019
die_errno(_("could not read file '%s'"), filename);
10011020
}
10021021
} else {
10031022
strbuf_getline_lf(&str, fp);
1023+
free(*read_bad);
10041024
*read_bad = strbuf_detach(&str, NULL);
10051025
strbuf_getline_lf(&str, fp);
1026+
free(*read_good);
10061027
*read_good = strbuf_detach(&str, NULL);
10071028
}
10081029
strbuf_release(&str);
@@ -1024,7 +1045,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
10241045
{
10251046
struct strvec rev_argv = STRVEC_INIT;
10261047
struct rev_info revs = REV_INFO_INIT;
1027-
struct commit_list *tried;
1048+
struct commit_list *tried = NULL;
10281049
int reaches = 0, all = 0, nr, steps;
10291050
enum bisect_error res = BISECT_OK;
10301051
struct object_id *bisect_rev;
@@ -1091,7 +1112,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
10911112
if (oideq(bisect_rev, current_bad_oid)) {
10921113
res = error_if_skipped_commits(tried, current_bad_oid);
10931114
if (res)
1094-
return res;
1115+
goto cleanup;
10951116
printf("%s is the first %s commit\n", oid_to_hex(bisect_rev),
10961117
term_bad);
10971118

@@ -1125,6 +1146,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
11251146

11261147
res = bisect_checkout(bisect_rev, no_checkout);
11271148
cleanup:
1149+
free_commit_list(tried);
11281150
release_revisions(&revs);
11291151
strvec_clear(&rev_argv);
11301152
return res;

bisect.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix);
7575

7676
int estimate_bisect_steps(int all);
7777

78-
void read_bisect_terms(const char **bad, const char **good);
78+
void read_bisect_terms(char **bad, char **good);
7979

8080
int bisect_clean_state(void);
8181

blame.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2931,6 +2931,7 @@ void setup_blame_bloom_data(struct blame_scoreboard *sb)
29312931
void cleanup_scoreboard(struct blame_scoreboard *sb)
29322932
{
29332933
free(sb->lineno);
2934+
free(sb->final_buf);
29342935
clear_prio_queue(&sb->commits);
29352936
oidset_clear(&sb->ignore_list);
29362937

blame.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ struct blame_scoreboard {
116116
* Used by many functions to obtain contents of the nth line,
117117
* indexed with scoreboard.lineno[blame_entry.lno].
118118
*/
119-
const char *final_buf;
119+
char *final_buf;
120120
unsigned long final_buf_size;
121121

122122
/* linked list of blames */

builtin/blame.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,12 +1216,6 @@ int cmd_blame(int argc,
12161216
output_option &= ~(OUTPUT_COLOR_LINE | OUTPUT_SHOW_AGE_WITH_COLOR);
12171217

12181218
output(&sb, output_option);
1219-
free((void *)sb.final_buf);
1220-
for (ent = sb.ent; ent; ) {
1221-
struct blame_entry *e = ent->next;
1222-
free(ent);
1223-
ent = e;
1224-
}
12251219

12261220
if (show_stats) {
12271221
printf("num read blob: %d\n", sb.num_read_blob);
@@ -1230,6 +1224,12 @@ int cmd_blame(int argc,
12301224
}
12311225

12321226
cleanup:
1227+
for (ent = sb.ent; ent; ) {
1228+
struct blame_entry *e = ent->next;
1229+
free(ent);
1230+
ent = e;
1231+
}
1232+
12331233
free(path);
12341234
cleanup_scoreboard(&sb);
12351235
release_revisions(&revs);

builtin/branch.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,7 @@ int cmd_branch(int argc,
722722
static struct ref_sorting *sorting;
723723
struct string_list sorting_options = STRING_LIST_INIT_DUP;
724724
struct ref_format format = REF_FORMAT_INIT;
725+
int ret;
725726

726727
struct option options[] = {
727728
OPT_GROUP(N_("Generic options")),
@@ -851,15 +852,15 @@ int cmd_branch(int argc,
851852
if (list)
852853
setup_auto_pager("branch", 1);
853854

854-
UNLEAK(sorting_options);
855-
856855
if (delete) {
857856
if (!argc)
858857
die(_("branch name required"));
859-
return delete_branches(argc, argv, delete > 1, filter.kind, quiet);
858+
ret = delete_branches(argc, argv, delete > 1, filter.kind, quiet);
859+
goto out;
860860
} else if (show_current) {
861861
print_current_branch_name();
862-
return 0;
862+
ret = 0;
863+
goto out;
863864
} else if (list) {
864865
/* git branch --list also shows HEAD when it is detached */
865866
if ((filter.kind & FILTER_REFS_BRANCHES) && filter.detached)
@@ -882,12 +883,13 @@ int cmd_branch(int argc,
882883
ref_sorting_release(sorting);
883884
ref_filter_clear(&filter);
884885
ref_format_clear(&format);
885-
return 0;
886+
887+
ret = 0;
888+
goto out;
886889
} else if (edit_description) {
887890
const char *branch_name;
888891
struct strbuf branch_ref = STRBUF_INIT;
889892
struct strbuf buf = STRBUF_INIT;
890-
int ret = 1; /* assume failure */
891893

892894
if (!argc) {
893895
if (filter.detached)
@@ -901,18 +903,22 @@ int cmd_branch(int argc,
901903
}
902904

903905
strbuf_addf(&branch_ref, "refs/heads/%s", branch_name);
904-
if (!refs_ref_exists(get_main_ref_store(the_repository), branch_ref.buf))
906+
if (!refs_ref_exists(get_main_ref_store(the_repository), branch_ref.buf)) {
905907
error((!argc || branch_checked_out(branch_ref.buf))
906908
? _("no commit on branch '%s' yet")
907909
: _("no branch named '%s'"),
908910
branch_name);
909-
else if (!edit_branch_description(branch_name))
911+
ret = 1;
912+
} else if (!edit_branch_description(branch_name)) {
910913
ret = 0; /* happy */
914+
} else {
915+
ret = 1;
916+
}
911917

912918
strbuf_release(&branch_ref);
913919
strbuf_release(&buf);
914920

915-
return ret;
921+
goto out;
916922
} else if (copy || rename) {
917923
if (!argc)
918924
die(_("branch name required"));
@@ -1000,12 +1006,17 @@ int cmd_branch(int argc,
10001006
create_branches_recursively(the_repository, branch_name,
10011007
start_name, NULL, force,
10021008
reflog, quiet, track, 0);
1003-
return 0;
1009+
ret = 0;
1010+
goto out;
10041011
}
10051012
create_branch(the_repository, branch_name, start_name, force, 0,
10061013
reflog, quiet, track, 0);
10071014
} else
10081015
usage_with_options(builtin_branch_usage, options);
10091016

1010-
return 0;
1017+
ret = 0;
1018+
1019+
out:
1020+
string_list_clear(&sorting_options, 0);
1021+
return ret;
10111022
}

builtin/clone.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1586,7 +1586,6 @@ int cmd_clone(int argc,
15861586
free(dir);
15871587
free(path);
15881588
free(repo_to_free);
1589-
UNLEAK(repo);
15901589
junk_mode = JUNK_LEAVE_ALL;
15911590

15921591
transport_ls_refs_options_release(&transport_ls_refs_options);

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/diff.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -628,6 +628,5 @@ int cmd_diff(int argc,
628628
release_revisions(&rev);
629629
object_array_clear(&ent);
630630
symdiff_release(&sdiff);
631-
UNLEAK(blob);
632631
return result;
633632
}

0 commit comments

Comments
 (0)