Skip to content

Commit

Permalink
Merge branch 'ps/leakfixes-more'
Browse files Browse the repository at this point in the history
More memory leaks have been plugged.

* ps/leakfixes-more: (29 commits)
  builtin/blame: fix leaking ignore revs files
  builtin/blame: fix leaking prefixed paths
  blame: fix leaking data for blame scoreboards
  line-range: plug leaking find functions
  merge: fix leaking merge bases
  builtin/merge: fix leaking `struct cmdnames` in `get_strategy()`
  sequencer: fix memory leaks in `make_script_with_merges()`
  builtin/clone: plug leaking HEAD ref in `wanted_peer_refs()`
  apply: fix leaking string in `match_fragment()`
  sequencer: fix leaking string buffer in `commit_staged_changes()`
  commit: fix leaking parents when calling `commit_tree_extended()`
  config: fix leaking "core.notesref" variable
  rerere: fix various trivial leaks
  builtin/stash: fix leak in `show_stash()`
  revision: free diff options
  builtin/log: fix leaking commit list in git-cherry(1)
  merge-recursive: fix memory leak when finalizing merge
  builtin/merge-recursive: fix leaking object ID bases
  builtin/difftool: plug memory leaks in `run_dir_diff()`
  object-name: free leaking object contexts
  ...
  • Loading branch information
gitster committed Jul 8, 2024
2 parents ecf7fc6 + fbf7a46 commit 3997614
Show file tree
Hide file tree
Showing 130 changed files with 591 additions and 272 deletions.
88 changes: 56 additions & 32 deletions apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ void clear_apply_state(struct apply_state *state)
strset_clear(&state->removed_symlinks);
strset_clear(&state->kept_symlinks);
strbuf_release(&state->root);
FREE_AND_NULL(state->fake_ancestor);

/* &state->fn_table is cleared at the end of apply_patch() */
}
Expand Down Expand Up @@ -2495,18 +2496,21 @@ static int match_fragment(struct apply_state *state,
int match_beginning, int match_end)
{
int i;
char *fixed_buf, *buf, *orig, *target;
struct strbuf fixed;
size_t fixed_len, postlen;
const char *orig, *target;
struct strbuf fixed = STRBUF_INIT;
size_t postlen;
int preimage_limit;
int ret;

if (preimage->nr + current_lno <= img->nr) {
/*
* The hunk falls within the boundaries of img.
*/
preimage_limit = preimage->nr;
if (match_end && (preimage->nr + current_lno != img->nr))
return 0;
if (match_end && (preimage->nr + current_lno != img->nr)) {
ret = 0;
goto out;
}
} else if (state->ws_error_action == correct_ws_error &&
(ws_rule & WS_BLANK_AT_EOF)) {
/*
Expand All @@ -2523,17 +2527,23 @@ static int match_fragment(struct apply_state *state,
* we are not removing blanks at the end, so we
* should reject the hunk at this position.
*/
return 0;
ret = 0;
goto out;
}

if (match_beginning && current_lno)
return 0;
if (match_beginning && current_lno) {
ret = 0;
goto out;
}

/* Quick hash check */
for (i = 0; i < preimage_limit; i++)
for (i = 0; i < preimage_limit; i++) {
if ((img->line[current_lno + i].flag & LINE_PATCHED) ||
(preimage->line[i].hash != img->line[current_lno + i].hash))
return 0;
(preimage->line[i].hash != img->line[current_lno + i].hash)) {
ret = 0;
goto out;
}
}

if (preimage_limit == preimage->nr) {
/*
Expand All @@ -2546,8 +2556,10 @@ static int match_fragment(struct apply_state *state,
if ((match_end
? (current + preimage->len == img->len)
: (current + preimage->len <= img->len)) &&
!memcmp(img->buf + current, preimage->buf, preimage->len))
return 1;
!memcmp(img->buf + current, preimage->buf, preimage->len)) {
ret = 1;
goto out;
}
} else {
/*
* The preimage extends beyond the end of img, so
Expand All @@ -2556,7 +2568,7 @@ static int match_fragment(struct apply_state *state,
* There must be one non-blank context line that match
* a line before the end of img.
*/
char *buf_end;
const char *buf, *buf_end;

buf = preimage->buf;
buf_end = buf;
Expand All @@ -2566,21 +2578,27 @@ static int match_fragment(struct apply_state *state,
for ( ; buf < buf_end; buf++)
if (!isspace(*buf))
break;
if (buf == buf_end)
return 0;
if (buf == buf_end) {
ret = 0;
goto out;
}
}

/*
* No exact match. If we are ignoring whitespace, run a line-by-line
* fuzzy matching. We collect all the line length information because
* we need it to adjust whitespace if we match.
*/
if (state->ws_ignore_action == ignore_ws_change)
return line_by_line_fuzzy_match(img, preimage, postimage,
current, current_lno, preimage_limit);
if (state->ws_ignore_action == ignore_ws_change) {
ret = line_by_line_fuzzy_match(img, preimage, postimage,
current, current_lno, preimage_limit);
goto out;
}

if (state->ws_error_action != correct_ws_error)
return 0;
if (state->ws_error_action != correct_ws_error) {
ret = 0;
goto out;
}

/*
* The hunk does not apply byte-by-byte, but the hash says
Expand Down Expand Up @@ -2609,7 +2627,7 @@ static int match_fragment(struct apply_state *state,
* but in this loop we will only handle the part of the
* preimage that falls within the file.
*/
strbuf_init(&fixed, preimage->len + 1);
strbuf_grow(&fixed, preimage->len + 1);
orig = preimage->buf;
target = img->buf + current;
for (i = 0; i < preimage_limit; i++) {
Expand Down Expand Up @@ -2645,8 +2663,10 @@ static int match_fragment(struct apply_state *state,
postlen += tgtfix.len;

strbuf_release(&tgtfix);
if (!match)
goto unmatch_exit;
if (!match) {
ret = 0;
goto out;
}

orig += oldlen;
target += tgtlen;
Expand All @@ -2667,9 +2687,13 @@ static int match_fragment(struct apply_state *state,
/* Try fixing the line in the preimage */
ws_fix_copy(&fixed, orig, oldlen, ws_rule, NULL);

for (j = fixstart; j < fixed.len; j++)
if (!isspace(fixed.buf[j]))
goto unmatch_exit;
for (j = fixstart; j < fixed.len; j++) {
if (!isspace(fixed.buf[j])) {
ret = 0;
goto out;
}
}


orig += oldlen;
}
Expand All @@ -2679,16 +2703,16 @@ static int match_fragment(struct apply_state *state,
* has whitespace breakages unfixed, and fixing them makes the
* hunk match. Update the context lines in the postimage.
*/
fixed_buf = strbuf_detach(&fixed, &fixed_len);
if (postlen < postimage->len)
postlen = 0;
update_pre_post_images(preimage, postimage,
fixed_buf, fixed_len, postlen);
return 1;
fixed.buf, fixed.len, postlen);

unmatch_exit:
ret = 1;

out:
strbuf_release(&fixed);
return 0;
return ret;
}

static int find_pos(struct apply_state *state,
Expand Down
2 changes: 1 addition & 1 deletion apply.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct apply_state {
struct repository *repo;
const char *index_file;
enum apply_verbosity apply_verbosity;
const char *fake_ancestor;
char *fake_ancestor;
const char *patch_input_file;
int line_termination;
struct strbuf root;
Expand Down
4 changes: 4 additions & 0 deletions blame.c
Original file line number Diff line number Diff line change
Expand Up @@ -2930,6 +2930,10 @@ void setup_blame_bloom_data(struct blame_scoreboard *sb)

void cleanup_scoreboard(struct blame_scoreboard *sb)
{
free(sb->lineno);
clear_prio_queue(&sb->commits);
oidset_clear(&sb->ignore_list);

if (sb->bloom_data) {
int i;
for (i = 0; i < sb->bloom_data->nr; i++) {
Expand Down
7 changes: 4 additions & 3 deletions builtin/am.c
Original file line number Diff line number Diff line change
Expand Up @@ -1573,8 +1573,8 @@ static int build_fake_ancestor(const struct am_state *state, const char *index_f
*/
static int fall_back_threeway(const struct am_state *state, const char *index_path)
{
struct object_id orig_tree, their_tree, our_tree;
const struct object_id *bases[1] = { &orig_tree };
struct object_id their_tree, our_tree;
struct object_id bases[1] = { 0 };
struct merge_options o;
struct commit *result;
char *their_tree_name;
Expand All @@ -1588,7 +1588,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa
discard_index(the_repository->index);
read_index_from(the_repository->index, index_path, get_git_dir());

if (write_index_as_tree(&orig_tree, the_repository->index, index_path, 0, NULL))
if (write_index_as_tree(&bases[0], the_repository->index, index_path, 0, NULL))
return error(_("Repository lacks necessary blobs to fall back on 3-way merge."));

say(state, stdout, _("Using index info to reconstruct a base tree..."));
Expand Down Expand Up @@ -1718,6 +1718,7 @@ static void do_commit(const struct am_state *state)

run_hooks("post-applypatch");

free_commit_list(parents);
strbuf_release(&sb);
}

Expand Down
7 changes: 5 additions & 2 deletions builtin/archive.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ int cmd_archive(int argc, const char **argv, const char *prefix)
N_("path to the remote git-upload-archive command")),
OPT_END()
};
int ret;

argc = parse_options(argc, argv, prefix, local_opts, NULL,
PARSE_OPT_KEEP_ALL);
Expand All @@ -104,6 +105,8 @@ int cmd_archive(int argc, const char **argv, const char *prefix)

setvbuf(stderr, NULL, _IOLBF, BUFSIZ);

UNLEAK(output);
return write_archive(argc, argv, prefix, the_repository, output, 0);
ret = write_archive(argc, argv, prefix, the_repository, output, 0);

free(output);
return ret;
}
8 changes: 5 additions & 3 deletions builtin/blame.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ static int no_whole_file_rename;
static int show_progress;
static char repeated_meta_color[COLOR_MAXLEN];
static int coloring_mode;
static struct string_list ignore_revs_file_list = STRING_LIST_INIT_NODUP;
static struct string_list ignore_revs_file_list = STRING_LIST_INIT_DUP;
static int mark_unblamable_lines;
static int mark_ignored_lines;

Expand Down Expand Up @@ -687,7 +687,7 @@ static unsigned parse_score(const char *arg)
return score;
}

static const char *add_prefix(const char *prefix, const char *path)
static char *add_prefix(const char *prefix, const char *path)
{
return prefix_path(prefix, prefix ? strlen(prefix) : 0, path);
}
Expand Down Expand Up @@ -725,6 +725,7 @@ static int git_blame_config(const char *var, const char *value,
if (ret)
return ret;
string_list_insert(&ignore_revs_file_list, str);
free(str);
return 0;
}
if (!strcmp(var, "blame.markunblamablelines")) {
Expand Down Expand Up @@ -866,7 +867,7 @@ static void build_ignorelist(struct blame_scoreboard *sb,
int cmd_blame(int argc, const char **argv, const char *prefix)
{
struct rev_info revs;
const char *path;
char *path = NULL;
struct blame_scoreboard sb;
struct blame_origin *o;
struct blame_entry *ent = NULL;
Expand Down Expand Up @@ -1227,6 +1228,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix)
}

cleanup:
free(path);
cleanup_scoreboard(&sb);
release_revisions(&revs);
return 0;
Expand Down
17 changes: 11 additions & 6 deletions builtin/cat-file.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
enum object_type type;
char *buf;
unsigned long size;
struct object_context obj_context;
struct object_context obj_context = {0};
struct object_info oi = OBJECT_INFO_INIT;
struct strbuf sb = STRBUF_INIT;
unsigned flags = OBJECT_INFO_LOOKUP_REPLACE;
Expand Down Expand Up @@ -163,7 +163,8 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
goto cleanup;

case 'e':
return !repo_has_object_file(the_repository, &oid);
ret = !repo_has_object_file(the_repository, &oid);
goto cleanup;

case 'w':

Expand Down Expand Up @@ -268,7 +269,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
ret = 0;
cleanup:
free(buf);
free(obj_context.path);
object_context_release(&obj_context);
return ret;
}

Expand Down Expand Up @@ -520,7 +521,7 @@ static void batch_one_object(const char *obj_name,
struct batch_options *opt,
struct expand_data *data)
{
struct object_context ctx;
struct object_context ctx = {0};
int flags =
GET_OID_HASH_ANY |
(opt->follow_symlinks ? GET_OID_FOLLOW_SYMLINKS : 0);
Expand Down Expand Up @@ -557,18 +558,22 @@ static void batch_one_object(const char *obj_name,
break;
}
fflush(stdout);
return;

goto out;
}

if (ctx.mode == 0) {
printf("symlink %"PRIuMAX"%c%s%c",
(uintmax_t)ctx.symlink_path.len,
opt->output_delim, ctx.symlink_path.buf, opt->output_delim);
fflush(stdout);
return;
goto out;
}

batch_object_write(obj_name, scratch, opt, data, NULL, 0);

out:
object_context_release(&ctx);
}

struct object_cb_data {
Expand Down
3 changes: 2 additions & 1 deletion builtin/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,8 @@ static struct ref *wanted_peer_refs(const struct ref *refs,
if (!option_branch)
remote_head = guess_remote_head(head, refs, 0);
else {
local_refs = NULL;
free_one_ref(head);
local_refs = head = NULL;
tail = &local_refs;
remote_head = copy_ref(find_remote_branch(refs, option_branch));
}
Expand Down
11 changes: 8 additions & 3 deletions builtin/commit-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)
N_("GPG sign commit"), PARSE_OPT_OPTARG, NULL, (intptr_t) "" },
OPT_END()
};
int ret;

git_config(git_default_config, NULL);

Expand All @@ -132,11 +133,15 @@ int cmd_commit_tree(int argc, const char **argv, const char *prefix)

if (commit_tree(buffer.buf, buffer.len, &tree_oid, parents, &commit_oid,
NULL, sign_commit)) {
strbuf_release(&buffer);
return 1;
ret = 1;
goto out;
}

printf("%s\n", oid_to_hex(&commit_oid));
ret = 0;

out:
free_commit_list(parents);
strbuf_release(&buffer);
return 0;
return ret;
}
Loading

0 comments on commit 3997614

Please sign in to comment.