Merge branch 'ab/unpack-trees-leakfix'

Leakfix.

* ab/unpack-trees-leakfix:
  sequencer: fix a memory leak in do_reset()
  sequencer: add a "goto cleanup" to do_reset()
  unpack-trees: don't leak memory in verify_clean_subdirectory()
This commit is contained in:
Junio C Hamano 2021-10-25 16:06:56 -07:00
commit bfa646c2cb
3 changed files with 19 additions and 22 deletions

View File

@ -3645,9 +3645,9 @@ static int do_reset(struct repository *r,
struct strbuf ref_name = STRBUF_INIT;
struct object_id oid;
struct lock_file lock = LOCK_INIT;
struct tree_desc desc;
struct tree_desc desc = { 0 };
struct tree *tree;
struct unpack_trees_options unpack_tree_opts;
struct unpack_trees_options unpack_tree_opts = { 0 };
int ret = 0;
if (repo_hold_locked_index(r, &lock, LOCK_REPORT_ON_ERROR) < 0)
@ -3679,14 +3679,11 @@ static int do_reset(struct repository *r,
strbuf_addf(&ref_name, "refs/rewritten/%.*s", len, name);
if (get_oid(ref_name.buf, &oid) &&
get_oid(ref_name.buf + strlen("refs/rewritten/"), &oid)) {
error(_("could not read '%s'"), ref_name.buf);
rollback_lock_file(&lock);
strbuf_release(&ref_name);
return -1;
ret = error(_("could not read '%s'"), ref_name.buf);
goto cleanup;
}
}
memset(&unpack_tree_opts, 0, sizeof(unpack_tree_opts));
setup_unpack_trees_porcelain(&unpack_tree_opts, "reset");
unpack_tree_opts.head_idx = 1;
unpack_tree_opts.src_index = r->index;
@ -3698,24 +3695,18 @@ static int do_reset(struct repository *r,
init_checkout_metadata(&unpack_tree_opts.meta, name, &oid, NULL);
if (repo_read_index_unmerged(r)) {
rollback_lock_file(&lock);
strbuf_release(&ref_name);
return error_resolve_conflict(_(action_name(opts)));
ret = error_resolve_conflict(_(action_name(opts)));
goto cleanup;
}
if (!fill_tree_descriptor(r, &desc, &oid)) {
error(_("failed to find tree of %s"), oid_to_hex(&oid));
rollback_lock_file(&lock);
free((void *)desc.buffer);
strbuf_release(&ref_name);
return -1;
ret = error(_("failed to find tree of %s"), oid_to_hex(&oid));
goto cleanup;
}
if (unpack_trees(1, &desc, &unpack_tree_opts)) {
rollback_lock_file(&lock);
free((void *)desc.buffer);
strbuf_release(&ref_name);
return -1;
ret = -1;
goto cleanup;
}
tree = parse_tree_indirect(&oid);
@ -3723,14 +3714,17 @@ static int do_reset(struct repository *r,
if (write_locked_index(r->index, &lock, COMMIT_LOCK) < 0)
ret = error(_("could not write index"));
free((void *)desc.buffer);
if (!ret)
ret = update_ref(reflog_message(opts, "reset", "'%.*s'",
len, name), "HEAD", &oid,
NULL, 0, UPDATE_REFS_MSG_ON_ERR);
cleanup:
free((void *)desc.buffer);
if (ret < 0)
rollback_lock_file(&lock);
strbuf_release(&ref_name);
clear_unpack_trees_porcelain(&unpack_tree_opts);
return ret;
}

View File

@ -20,6 +20,8 @@ In the test, these paths are used:
rezrov - in H, deleted in M
yomin - not in H or M
'
TEST_PASSES_SANITIZE_LEAK=true
. ./test-lib.sh
. "$TEST_DIRECTORY"/lib-read-tree.sh

View File

@ -2156,9 +2156,10 @@ static int verify_clean_subdirectory(const struct cache_entry *ce,
if (o->dir)
d.exclude_per_dir = o->dir->exclude_per_dir;
i = read_directory(&d, o->src_index, pathbuf, namelen+1, NULL);
dir_clear(&d);
free(pathbuf);
if (i)
return add_rejected_path(o, ERROR_NOT_UPTODATE_DIR, ce->name);
free(pathbuf);
return cnt;
}