Skip to content

Commit db6bfb9

Browse files
avargitster
authored andcommitted
bundle cmd: stop leaking memory from parse_options_cmd_bundle()
Fix a memory leak from the prefix_filename() function introduced with its use in 3b754ee (bundle: use prefix_filename with bundle path, 2017-03-20). As noted in that commit the leak was intentional as a part of being sloppy about freeing resources just before we exit, I'm changing this because I'll be fixing other memory leaks in the bundle API (including the library version) in subsequent commits. It's easier to reason about those fixes if valgrind runs cleanly at the end without any leaks whatsoever. An earlier version of this change[1] went out of its way to not leak memory on the die() codepaths here, but doing so will only avoid reports of potential leaks under heap-only leak trackers such as valgrind, not the SANITIZE=leak mode. Avoiding those leaks as well might be useful to enable us to run cleanly under the likes of valgrind in the future. But for now the relative verbosity of the resulting code, and the fact that we don't have some valgrind or SANITIZE=leak mode as part of our CI (it's only run ad-hoc, see [2]), means we're not worrying about that for now. 1. https://lore.kernel.org/git/[email protected]/ 2. https://lore.kernel.org/git/[email protected]/ Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Acked-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 670b81a commit db6bfb9

File tree

1 file changed

+41
-21
lines changed

1 file changed

+41
-21
lines changed

builtin/bundle.c

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ static int parse_options_cmd_bundle(int argc,
4646
const char* prefix,
4747
const char * const usagestr[],
4848
const struct option options[],
49-
const char **bundle_file) {
49+
char **bundle_file) {
5050
int newargc;
5151
newargc = parse_options(argc, argv, NULL, options, usagestr,
5252
PARSE_OPT_STOP_AT_NON_OPTION);
@@ -61,7 +61,7 @@ static int cmd_bundle_create(int argc, const char **argv, const char *prefix) {
6161
int progress = isatty(STDERR_FILENO);
6262
struct strvec pack_opts;
6363
int version = -1;
64-
64+
int ret;
6565
struct option options[] = {
6666
OPT_SET_INT('q', "quiet", &progress,
6767
N_("do not show progress meter"), 0),
@@ -76,7 +76,7 @@ static int cmd_bundle_create(int argc, const char **argv, const char *prefix) {
7676
N_("specify bundle format version")),
7777
OPT_END()
7878
};
79-
const char* bundle_file;
79+
char *bundle_file;
8080

8181
argc = parse_options_cmd_bundle(argc, argv, prefix,
8282
builtin_bundle_create_usage, options, &bundle_file);
@@ -94,75 +94,95 @@ static int cmd_bundle_create(int argc, const char **argv, const char *prefix) {
9494

9595
if (!startup_info->have_repository)
9696
die(_("Need a repository to create a bundle."));
97-
return !!create_bundle(the_repository, bundle_file, argc, argv, &pack_opts, version);
97+
ret = !!create_bundle(the_repository, bundle_file, argc, argv, &pack_opts, version);
98+
free(bundle_file);
99+
return ret;
98100
}
99101

100102
static int cmd_bundle_verify(int argc, const char **argv, const char *prefix) {
101103
struct bundle_header header;
102104
int bundle_fd = -1;
103105
int quiet = 0;
104-
106+
int ret;
105107
struct option options[] = {
106108
OPT_BOOL('q', "quiet", &quiet,
107109
N_("do not show bundle details")),
108110
OPT_END()
109111
};
110-
const char* bundle_file;
112+
char *bundle_file;
111113

112114
argc = parse_options_cmd_bundle(argc, argv, prefix,
113115
builtin_bundle_verify_usage, options, &bundle_file);
114116
/* bundle internals use argv[1] as further parameters */
115117

116118
memset(&header, 0, sizeof(header));
117-
if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)
118-
return 1;
119+
if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0) {
120+
ret = 1;
121+
goto cleanup;
122+
}
119123
close(bundle_fd);
120-
if (verify_bundle(the_repository, &header, !quiet))
121-
return 1;
124+
if (verify_bundle(the_repository, &header, !quiet)) {
125+
ret = 1;
126+
goto cleanup;
127+
}
128+
122129
fprintf(stderr, _("%s is okay\n"), bundle_file);
123-
return 0;
130+
ret = 0;
131+
cleanup:
132+
free(bundle_file);
133+
return ret;
124134
}
125135

126136
static int cmd_bundle_list_heads(int argc, const char **argv, const char *prefix) {
127137
struct bundle_header header;
128138
int bundle_fd = -1;
129-
139+
int ret;
130140
struct option options[] = {
131141
OPT_END()
132142
};
133-
const char* bundle_file;
143+
char *bundle_file;
134144

135145
argc = parse_options_cmd_bundle(argc, argv, prefix,
136146
builtin_bundle_list_heads_usage, options, &bundle_file);
137147
/* bundle internals use argv[1] as further parameters */
138148

139149
memset(&header, 0, sizeof(header));
140-
if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)
141-
return 1;
150+
if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0) {
151+
ret = 1;
152+
goto cleanup;
153+
}
142154
close(bundle_fd);
143-
return !!list_bundle_refs(&header, argc, argv);
155+
ret = !!list_bundle_refs(&header, argc, argv);
156+
cleanup:
157+
free(bundle_file);
158+
return ret;
144159
}
145160

146161
static int cmd_bundle_unbundle(int argc, const char **argv, const char *prefix) {
147162
struct bundle_header header;
148163
int bundle_fd = -1;
149-
164+
int ret;
150165
struct option options[] = {
151166
OPT_END()
152167
};
153-
const char* bundle_file;
168+
char *bundle_file;
154169

155170
argc = parse_options_cmd_bundle(argc, argv, prefix,
156171
builtin_bundle_unbundle_usage, options, &bundle_file);
157172
/* bundle internals use argv[1] as further parameters */
158173

159174
memset(&header, 0, sizeof(header));
160-
if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0)
161-
return 1;
175+
if ((bundle_fd = read_bundle_header(bundle_file, &header)) < 0) {
176+
ret = 1;
177+
goto cleanup;
178+
}
162179
if (!startup_info->have_repository)
163180
die(_("Need a repository to unbundle."));
164-
return !!unbundle(the_repository, &header, bundle_fd, 0) ||
181+
ret = !!unbundle(the_repository, &header, bundle_fd, 0) ||
165182
list_bundle_refs(&header, argc, argv);
183+
cleanup:
184+
free(bundle_file);
185+
return ret;
166186
}
167187

168188
int cmd_bundle(int argc, const char **argv, const char *prefix)

0 commit comments

Comments
 (0)