Skip to content

Commit 1a89796

Browse files
committed
Merge branch 'ab/ref-filter-leakfix' into jc/fix-ref-sorting-parse
* ab/ref-filter-leakfix: branch: use ref_sorting_release() ref-filter API user: add and use a ref_sorting_release() tag: use a "goto cleanup" pattern, leak less memory
2 parents 9d530dc + d72d4f9 commit 1a89796

File tree

5 files changed

+34
-16
lines changed

5 files changed

+34
-16
lines changed

builtin/branch.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,8 @@ static char *build_format(struct ref_filter *filter, int maxwidth, const char *r
407407
return strbuf_detach(&fmt, NULL);
408408
}
409409

410-
static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sorting, struct ref_format *format)
410+
static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sorting,
411+
struct ref_format *format, struct string_list *output)
411412
{
412413
int i;
413414
struct ref_array array;
@@ -449,7 +450,7 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin
449450
if (column_active(colopts)) {
450451
assert(!filter->verbose && "--column and --verbose are incompatible");
451452
/* format to a string_list to let print_columns() do its job */
452-
string_list_append(&output, out.buf);
453+
string_list_append(output, out.buf);
453454
} else {
454455
fwrite(out.buf, 1, out.len, stdout);
455456
putchar('\n');
@@ -753,9 +754,10 @@ int cmd_branch(int argc, const char **argv, const char *prefix)
753754
ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase);
754755
ref_sorting_set_sort_flags_all(
755756
sorting, REF_SORTING_DETACHED_HEAD_FIRST, 1);
756-
print_ref_list(&filter, sorting, &format);
757+
print_ref_list(&filter, sorting, &format, &output);
757758
print_columns(&output, colopts, NULL);
758759
string_list_clear(&output, 0);
760+
ref_sorting_release(sorting);
759761
return 0;
760762
} else if (edit_description) {
761763
const char *branch_name;

builtin/for-each-ref.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,6 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
9696
ref_array_clear(&array);
9797
free_commit_list(filter.with_commit);
9898
free_commit_list(filter.no_commit);
99-
UNLEAK(sorting);
99+
ref_sorting_release(sorting);
100100
return 0;
101101
}

builtin/tag.c

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
432432
int annotate = 0, force = 0;
433433
int cmdmode = 0, create_tag_object = 0;
434434
const char *msgfile = NULL, *keyid = NULL;
435-
struct msg_arg msg = { 0, STRBUF_INIT };
435+
struct msg_arg msg = { .buf = STRBUF_INIT };
436436
struct ref_transaction *transaction;
437437
struct strbuf err = STRBUF_INIT;
438438
struct ref_filter filter;
@@ -482,6 +482,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
482482
OPT_BOOL('i', "ignore-case", &icase, N_("sorting and filtering are case insensitive")),
483483
OPT_END()
484484
};
485+
int ret = 0;
485486

486487
setup_ref_filter_porcelain_msg();
487488

@@ -529,7 +530,6 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
529530
ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase);
530531
filter.ignore_case = icase;
531532
if (cmdmode == 'l') {
532-
int ret;
533533
if (column_active(colopts)) {
534534
struct column_options copts;
535535
memset(&copts, 0, sizeof(copts));
@@ -540,7 +540,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
540540
ret = list_tags(&filter, sorting, &format);
541541
if (column_active(colopts))
542542
stop_column_filter();
543-
return ret;
543+
goto cleanup;
544544
}
545545
if (filter.lines != -1)
546546
die(_("-n option is only allowed in list mode"));
@@ -552,12 +552,15 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
552552
die(_("--points-at option is only allowed in list mode"));
553553
if (filter.reachable_from || filter.unreachable_from)
554554
die(_("--merged and --no-merged options are only allowed in list mode"));
555-
if (cmdmode == 'd')
556-
return delete_tags(argv);
555+
if (cmdmode == 'd') {
556+
ret = delete_tags(argv);
557+
goto cleanup;
558+
}
557559
if (cmdmode == 'v') {
558560
if (format.format && verify_ref_format(&format))
559561
usage_with_options(git_tag_usage, options);
560-
return for_each_tag_name(argv, verify_tag, &format);
562+
ret = for_each_tag_name(argv, verify_tag, &format);
563+
goto cleanup;
561564
}
562565

563566
if (msg.given || msgfile) {
@@ -626,10 +629,12 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
626629
printf(_("Updated tag '%s' (was %s)\n"), tag,
627630
find_unique_abbrev(&prev, DEFAULT_ABBREV));
628631

629-
UNLEAK(buf);
630-
UNLEAK(ref);
631-
UNLEAK(reflog_msg);
632-
UNLEAK(msg);
633-
UNLEAK(err);
634-
return 0;
632+
cleanup:
633+
ref_sorting_release(sorting);
634+
strbuf_release(&buf);
635+
strbuf_release(&ref);
636+
strbuf_release(&reflog_msg);
637+
strbuf_release(&msg.buf);
638+
strbuf_release(&err);
639+
return ret;
635640
}

ref-filter.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2705,6 +2705,15 @@ int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset)
27052705
return 0;
27062706
}
27072707

2708+
void ref_sorting_release(struct ref_sorting *sorting)
2709+
{
2710+
while (sorting) {
2711+
struct ref_sorting *next = sorting->next;
2712+
free(sorting);
2713+
sorting = next;
2714+
}
2715+
}
2716+
27082717
int parse_opt_merge_filter(const struct option *opt, const char *arg, int unset)
27092718
{
27102719
struct ref_filter *rf = opt->value;

ref-filter.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ void parse_ref_sorting(struct ref_sorting **sorting_tail, const char *atom);
127127
int parse_opt_ref_sorting(const struct option *opt, const char *arg, int unset);
128128
/* Default sort option based on refname */
129129
struct ref_sorting *ref_default_sorting(void);
130+
/* Release a "struct ref_sorting" */
131+
void ref_sorting_release(struct ref_sorting *);
130132
/* Function to parse --merged and --no-merged options */
131133
int parse_opt_merge_filter(const struct option *opt, const char *arg, int unset);
132134
/* Get the current HEAD's description */

0 commit comments

Comments
 (0)