Merge branch 'ab/plug-random-leaks'

Plug random memory leaks.

* ab/plug-random-leaks:
  repository.c: free the "path cache" in repo_clear()
  range-diff: plug memory leak in read_patches()
  range-diff: plug memory leak in common invocation
  lockfile API users: simplify and don't leak "path"
  commit-graph: stop fill_oids_from_packs() progress on error and free()
  commit-graph: fix memory leak in misused string_list API
  submodule--helper: fix trivial leak in module_add()
  transport: stop needlessly copying bundle header references
  bundle: call strvec_clear() on allocated strvec
  remote-curl.c: free memory in cmd_main()
  urlmatch.c: add and use a *_release() function
  diff.c: free "buf" in diff_words_flush()
  merge-base: free() allocated "struct commit **" list
  index-pack: fix memory leaks
This commit is contained in:
Junio C Hamano 2022-03-13 22:56:18 +00:00
commit ccafbbfb4e
21 changed files with 114 additions and 63 deletions

View File

@ -219,13 +219,18 @@ static void free_fragment_list(struct fragment *list)
}
}
static void free_patch(struct patch *patch)
void release_patch(struct patch *patch)
{
free_fragment_list(patch->fragments);
free(patch->def_name);
free(patch->old_name);
free(patch->new_name);
free(patch->result);
}
static void free_patch(struct patch *patch)
{
release_patch(patch);
free(patch);
}

View File

@ -173,6 +173,8 @@ int parse_git_diff_header(struct strbuf *root,
unsigned int size,
struct patch *patch);
void release_patch(struct patch *patch);
/*
* Some aspects of the apply behavior are controlled by the following
* bits in the "options" parameter passed to apply_all_patches().

View File

@ -93,6 +93,7 @@ static int cmd_bundle_create(int argc, const char **argv, const char *prefix) {
if (!startup_info->have_repository)
die(_("Need a repository to create a bundle."));
ret = !!create_bundle(the_repository, bundle_file, argc, argv, &pack_opts, version);
strvec_clear(&pack_opts);
free(bundle_file);
return ret;
}

View File

@ -192,7 +192,7 @@ static int git_commit_graph_write_config(const char *var, const char *value,
static int graph_write(int argc, const char **argv)
{
struct string_list pack_indexes = STRING_LIST_INIT_NODUP;
struct string_list pack_indexes = STRING_LIST_INIT_DUP;
struct strbuf buf = STRBUF_INIT;
struct oidset commits = OIDSET_INIT;
struct object_directory *odb = NULL;
@ -273,8 +273,8 @@ static int graph_write(int argc, const char **argv)
if (opts.stdin_packs) {
while (strbuf_getline(&buf, stdin) != EOF)
string_list_append(&pack_indexes,
strbuf_detach(&buf, NULL));
string_list_append_nodup(&pack_indexes,
strbuf_detach(&buf, NULL));
} else if (opts.stdin_commits) {
oidset_init(&commits, 0);
if (opts.progress)

View File

@ -612,7 +612,7 @@ static int get_urlmatch(const char *var, const char *url)
strbuf_release(&matched->value);
}
string_list_clear(&config.vars, 1);
urlmatch_config_release(&config);
string_list_clear(&values, 1);
free(config.url.url);

View File

@ -1113,6 +1113,7 @@ static void *threaded_second_pass(void *data)
list_add(&child->list, &work_head);
base_cache_used += child->size;
prune_base_data(NULL);
free_base_data(child);
} else {
/*
* This child does not have its own children. It may be
@ -1135,6 +1136,7 @@ static void *threaded_second_pass(void *data)
p = next_p;
}
FREE_AND_NULL(child);
}
work_unlock();
}
@ -1428,6 +1430,7 @@ static void fix_unresolved_deltas(struct hashfile *f)
* object).
*/
append_obj_to_pack(f, d->oid.hash, data, size, type);
free(data);
threaded_second_pass(NULL);
display_progress(progress, nr_resolved_deltas);
@ -1707,6 +1710,7 @@ static void show_pack_info(int stat_only)
i + 1,
chain_histogram[i]);
}
free(chain_histogram);
}
int cmd_index_pack(int argc, const char **argv, const char *prefix)
@ -1936,6 +1940,7 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
if (do_fsck_object && fsck_finish(&fsck_options))
die(_("fsck error in pack objects"));
free(opts.anomaly);
free(objects);
strbuf_release(&index_name_buf);
strbuf_release(&rev_index_name_buf);

View File

@ -138,6 +138,7 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix)
int rev_nr = 0;
int show_all = 0;
int cmdmode = 0;
int ret;
struct option options[] = {
OPT_BOOL('a', "all", &show_all, N_("output all common ancestors")),
@ -186,5 +187,7 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix)
ALLOC_ARRAY(rev, argc);
while (argc-- > 0)
rev[rev_nr++] = get_commit_reference(*argv++);
return show_merge_base(rev, rev_nr, show_all);
ret = show_merge_base(rev, rev_nr, show_all);
free(rev);
return ret;
}

View File

@ -329,11 +329,11 @@ static int write_patterns_and_update(struct pattern_list *pl)
fd = hold_lock_file_for_update(&lk, sparse_filename,
LOCK_DIE_ON_ERROR);
free(sparse_filename);
result = update_working_directory(pl);
if (result) {
rollback_lock_file(&lk);
free(sparse_filename);
clear_pattern_list(pl);
update_working_directory(NULL);
return result;
@ -349,7 +349,6 @@ static int write_patterns_and_update(struct pattern_list *pl)
fflush(fp);
commit_lock_file(&lk);
free(sparse_filename);
clear_pattern_list(pl);
return 0;

View File

@ -3309,6 +3309,7 @@ static int module_add(int argc, const char **argv, const char *prefix)
{
int force = 0, quiet = 0, progress = 0, dissociate = 0;
struct add_data add_data = ADD_DATA_INIT;
char *to_free = NULL;
struct option options[] = {
OPT_STRING('b', "branch", &add_data.branch, N_("branch"),
@ -3360,7 +3361,8 @@ static int module_add(int argc, const char **argv, const char *prefix)
"of the working tree"));
/* dereference source url relative to parent's url */
add_data.realrepo = resolve_relative_url(add_data.repo, NULL, 1);
to_free = resolve_relative_url(add_data.repo, NULL, 1);
add_data.realrepo = to_free;
} else if (is_dir_sep(add_data.repo[0]) || strchr(add_data.repo, ':')) {
add_data.realrepo = add_data.repo;
} else {
@ -3413,6 +3415,7 @@ static int module_add(int argc, const char **argv, const char *prefix)
}
configure_added_submodule(&add_data);
free(add_data.sm_path);
free(to_free);
return 0;
}

View File

@ -1679,12 +1679,13 @@ int write_commit_graph_reachable(struct object_directory *odb,
}
static int fill_oids_from_packs(struct write_commit_graph_context *ctx,
struct string_list *pack_indexes)
const struct string_list *pack_indexes)
{
uint32_t i;
struct strbuf progress_title = STRBUF_INIT;
struct strbuf packname = STRBUF_INIT;
int dirlen;
int ret = 0;
strbuf_addf(&packname, "%s/pack/", ctx->odb->path);
dirlen = packname.len;
@ -1703,12 +1704,12 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx,
strbuf_addstr(&packname, pack_indexes->items[i].string);
p = add_packed_git(packname.buf, packname.len, 1);
if (!p) {
error(_("error adding pack %s"), packname.buf);
return -1;
ret = error(_("error adding pack %s"), packname.buf);
goto cleanup;
}
if (open_pack_index(p)) {
error(_("error opening index for %s"), packname.buf);
return -1;
ret = error(_("error opening index for %s"), packname.buf);
goto cleanup;
}
for_each_object_in_pack(p, add_packed_commits, ctx,
FOR_EACH_OBJECT_PACK_ORDER);
@ -1716,11 +1717,12 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx,
free(p);
}
cleanup:
stop_progress(&ctx->progress);
strbuf_release(&progress_title);
strbuf_release(&packname);
return 0;
return ret;
}
static int fill_oids_from_commits(struct write_commit_graph_context *ctx,
@ -1852,6 +1854,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
hold_lock_file_for_update_mode(&lk, lock_name,
LOCK_DIE_ON_ERROR, 0444);
free(lock_name);
fd = git_mkstemp_mode(ctx->graph_name, 0444);
if (fd < 0) {
@ -1976,6 +1979,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx)
} else {
char *graph_name = get_commit_graph_filename(ctx->odb);
unlink(graph_name);
free(graph_name);
}
ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1] = xstrdup(hash_to_hex(file_hash));
@ -2259,7 +2263,7 @@ out:
}
int write_commit_graph(struct object_directory *odb,
struct string_list *pack_indexes,
const struct string_list *const pack_indexes,
struct oidset *commits,
enum commit_graph_write_flags flags,
const struct commit_graph_opts *opts)

View File

@ -142,7 +142,7 @@ int write_commit_graph_reachable(struct object_directory *odb,
enum commit_graph_write_flags flags,
const struct commit_graph_opts *opts);
int write_commit_graph(struct object_directory *odb,
struct string_list *pack_indexes,
const struct string_list *pack_indexes,
struct oidset *commits,
enum commit_graph_write_flags flags,
const struct commit_graph_opts *opts);

View File

@ -130,6 +130,7 @@ static void credential_apply_config(struct credential *c)
git_config(urlmatch_config_entry, &config);
string_list_clear(&config.vars, 1);
free(normalized_url);
urlmatch_config_release(&config);
strbuf_release(&url);
c->configured = 1;

1
diff.c
View File

@ -2150,6 +2150,7 @@ static void diff_words_flush(struct emit_callback *ecbdata)
for (i = 0; i < wol->nr; i++)
free((void *)wol->buf[i].line);
free(wol->buf);
wol->nr = 0;
}

14
path.h
View File

@ -169,20 +169,6 @@ void report_linked_checkout_garbage(void);
return r->cached_paths.var; \
}
struct path_cache {
const char *squash_msg;
const char *merge_msg;
const char *merge_rr;
const char *merge_mode;
const char *merge_head;
const char *merge_autostash;
const char *auto_merge;
const char *fetch_head;
const char *shallow;
};
#define PATH_CACHE_INIT { 0 }
const char *git_path_squash_msg(struct repository *r);
const char *git_path_merge_msg(struct repository *r);
const char *git_path_merge_rr(struct repository *r);

View File

@ -40,6 +40,7 @@ static int read_patches(const char *range, struct string_list *list,
char *line, *current_filename = NULL;
ssize_t len;
size_t size;
int ret = -1;
strvec_pushl(&cp.args, "log", "--no-color", "-p", "--no-merges",
"--reverse", "--date-order", "--decorate=no",
@ -68,10 +69,10 @@ static int read_patches(const char *range, struct string_list *list,
if (strbuf_read(&contents, cp.out, 0) < 0) {
error_errno(_("could not read `log` output"));
finish_command(&cp);
return -1;
goto cleanup;
}
if (finish_command(&cp))
return -1;
goto cleanup;
line = contents.buf;
size = contents.len;
@ -95,12 +96,9 @@ static int read_patches(const char *range, struct string_list *list,
CALLOC_ARRAY(util, 1);
if (get_oid(p, &util->oid)) {
error(_("could not parse commit '%s'"), p);
free(util);
free(current_filename);
FREE_AND_NULL(util);
string_list_clear(list, 1);
strbuf_release(&buf);
strbuf_release(&contents);
return -1;
goto cleanup;
}
util->matching = -1;
in_header = 1;
@ -111,11 +109,8 @@ static int read_patches(const char *range, struct string_list *list,
error(_("could not parse first line of `log` output: "
"did not start with 'commit ': '%s'"),
line);
free(current_filename);
string_list_clear(list, 1);
strbuf_release(&buf);
strbuf_release(&contents);
return -1;
goto cleanup;
}
if (starts_with(line, "diff --git")) {
@ -136,12 +131,9 @@ static int read_patches(const char *range, struct string_list *list,
if (len < 0) {
error(_("could not parse git header '%.*s'"),
orig_len, line);
free(util);
free(current_filename);
FREE_AND_NULL(util);
string_list_clear(list, 1);
strbuf_release(&buf);
strbuf_release(&contents);
return -1;
goto cleanup;
}
strbuf_addstr(&buf, " ## ");
if (patch.is_new > 0)
@ -165,6 +157,7 @@ static int read_patches(const char *range, struct string_list *list,
patch.old_mode, patch.new_mode);
strbuf_addstr(&buf, " ##");
release_patch(&patch);
} else if (in_header) {
if (starts_with(line, "Author: ")) {
strbuf_addstr(&buf, " ## Metadata ##\n");
@ -218,6 +211,9 @@ static int read_patches(const char *range, struct string_list *list,
strbuf_addch(&buf, '\n');
util->diffsize++;
}
ret = 0;
cleanup:
strbuf_release(&contents);
if (util)
@ -225,7 +221,7 @@ static int read_patches(const char *range, struct string_list *list,
strbuf_release(&buf);
free(current_filename);
return 0;
return ret;
}
static int patch_util_cmp(const void *dummy, const struct patch_util *a,

View File

@ -1472,11 +1472,12 @@ int cmd_main(int argc, const char **argv)
{
struct strbuf buf = STRBUF_INIT;
int nongit;
int ret = 1;
setup_git_directory_gently(&nongit);
if (argc < 2) {
error(_("remote-curl: usage: git remote-curl <remote> [<url>]"));
return 1;
goto cleanup;
}
options.verbosity = 1;
@ -1508,7 +1509,7 @@ int cmd_main(int argc, const char **argv)
if (strbuf_getline_lf(&buf, stdin) == EOF) {
if (ferror(stdin))
error(_("remote-curl: error reading command stream from git"));
return 1;
goto cleanup;
}
if (buf.len == 0)
break;
@ -1556,12 +1557,15 @@ int cmd_main(int argc, const char **argv)
break;
} else {
error(_("remote-curl: unknown command '%s' from git"), buf.buf);
return 1;
goto cleanup;
}
strbuf_reset(&buf);
} while (1);
http_cleanup();
ret = 0;
cleanup:
strbuf_release(&buf);
return 0;
return ret;
}

View File

@ -240,6 +240,20 @@ out:
return ret;
}
static void repo_clear_path_cache(struct repo_path_cache *cache)
{
FREE_AND_NULL(cache->squash_msg);
FREE_AND_NULL(cache->squash_msg);
FREE_AND_NULL(cache->merge_msg);
FREE_AND_NULL(cache->merge_rr);
FREE_AND_NULL(cache->merge_mode);
FREE_AND_NULL(cache->merge_head);
FREE_AND_NULL(cache->merge_autostash);
FREE_AND_NULL(cache->auto_merge);
FREE_AND_NULL(cache->fetch_head);
FREE_AND_NULL(cache->shallow);
}
void repo_clear(struct repository *repo)
{
FREE_AND_NULL(repo->gitdir);
@ -280,6 +294,8 @@ void repo_clear(struct repository *repo)
remote_state_clear(repo->remote_state);
FREE_AND_NULL(repo->remote_state);
}
repo_clear_path_cache(&repo->cached_paths);
}
int repo_read_index(struct repository *repo)

View File

@ -44,6 +44,18 @@ struct repo_settings {
int core_multi_pack_index;
};
struct repo_path_cache {
char *squash_msg;
char *merge_msg;
char *merge_rr;
char *merge_mode;
char *merge_head;
char *merge_autostash;
char *auto_merge;
char *fetch_head;
char *shallow;
};
struct repository {
/* Environment */
/*
@ -82,7 +94,7 @@ struct repository {
/*
* Contains path to often used file names.
*/
struct path_cache cached_paths;
struct repo_path_cache cached_paths;
/*
* Path to the repository's graft file.

View File

@ -125,6 +125,21 @@ struct bundle_transport_data {
unsigned get_refs_from_bundle_called : 1;
};
static void get_refs_from_bundle_inner(struct transport *transport)
{
struct bundle_transport_data *data = transport->data;
data->get_refs_from_bundle_called = 1;
if (data->fd > 0)
close(data->fd);
data->fd = read_bundle_header(transport->url, &data->header);
if (data->fd < 0)
die(_("could not read bundle '%s'"), transport->url);
transport->hash_algo = data->header.hash_algo;
}
static struct ref *get_refs_from_bundle(struct transport *transport,
int for_push,
struct transport_ls_refs_options *transport_options)
@ -136,15 +151,7 @@ static struct ref *get_refs_from_bundle(struct transport *transport,
if (for_push)
return NULL;
data->get_refs_from_bundle_called = 1;
if (data->fd > 0)
close(data->fd);
data->fd = read_bundle_header(transport->url, &data->header);
if (data->fd < 0)
die(_("could not read bundle '%s'"), transport->url);
transport->hash_algo = data->header.hash_algo;
get_refs_from_bundle_inner(transport);
for (i = 0; i < data->header.references.nr; i++) {
struct string_list_item *e = data->header.references.items + i;
@ -169,7 +176,7 @@ static int fetch_refs_from_bundle(struct transport *transport,
strvec_push(&extra_index_pack_args, "-v");
if (!data->get_refs_from_bundle_called)
get_refs_from_bundle(transport, 0, NULL);
get_refs_from_bundle_inner(transport);
ret = unbundle(the_repository, &data->header, data->fd,
&extra_index_pack_args);
transport->hash_algo = data->header.hash_algo;

View File

@ -611,3 +611,8 @@ int urlmatch_config_entry(const char *var, const char *value, void *cb)
strbuf_release(&synthkey);
return retval;
}
void urlmatch_config_release(struct urlmatch_config *config)
{
string_list_clear(&config->vars, 1);
}

View File

@ -71,5 +71,6 @@ struct urlmatch_config {
}
int urlmatch_config_entry(const char *var, const char *value, void *cb);
void urlmatch_config_release(struct urlmatch_config *config);
#endif /* URL_MATCH_H */