various: add missing clear_pathspec(), fix leaks

Fix memory leaks resulting from a missing clear_pathspec(). - archive.c: Plug a leak in the "struct archiver_args", and clear_pathspec() the "pathspec" member that the "parse_pathspec_arg()" call in this function populates. - builtin/clean.c: Fix a memory leak that's been with us since 893d839970c (clean: convert to use parse_pathspec, 2013-07-14). - builtin/reset.c: Add clear_pathspec() calls to cmd_reset(), including to the codepaths where we'd return early. - builtin/stash.c: Call clear_pathspec() on the pathspec initialized in push_stash(). Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ævar Arnfjörð Bjarmason committed Feb 7, 2023 at 00:07 UTC 7615cf94d2af0f9ae71c4302092990e635f23a8f
10 files changed +24 -5
archive.c
+1
@@ -710,6 +710,7 @@ int write_archive(int argc, const char **argv, const char *prefix,
710
711 string_list_clear_func(&args.extra_files, extra_file_info_clear);
712 free(args.refname);
713 + clear_pathspec(&args.pathspec);
714
715 return rc;
716 }
builtin/clean.c
+1
@@ -1092,5 +1092,6 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
1092 strbuf_release(&buf);
1093 string_list_clear(&del_list, 0);
1094 string_list_clear(&exclude_list, 0);
1095 + clear_pathspec(&pathspec);
1096 return (errors != 0);
1097 }
builtin/reset.c
+8 -3
@@ -390,7 +390,8 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
390 if (reset_type != NONE)
391 die(_("options '%s' and '%s' cannot be used together"), "--patch", "--{hard,mixed,soft}");
392 trace2_cmd_mode("patch-interactive");
393 - return run_add_interactive(rev, "--patch=reset", &pathspec);
393 + update_ref_status = run_add_interactive(rev, "--patch=reset", &pathspec);
394 + goto cleanup;
395 }
396
397 /* git reset tree [--] paths... can be used to
@@ -439,8 +440,10 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
440 LOCK_DIE_ON_ERROR);
441 if (reset_type == MIXED) {
442 int flags = quiet ? REFRESH_QUIET : REFRESH_IN_PORCELAIN;
442 - if (read_from_tree(&pathspec, &oid, intent_to_add))
443 - return 1;
443 + if (read_from_tree(&pathspec, &oid, intent_to_add)) {
444 + update_ref_status = 1;
445 + goto cleanup;
446 + }
447 the_index.updated_skipworktree = 1;
448 if (!no_refresh && get_git_work_tree()) {
449 uint64_t t_begin, t_delta_in_ms;
@@ -488,5 +491,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix)
491
492 discard_index(&the_index);
493
494 +cleanup:
495 + clear_pathspec(&pathspec);
496 return update_ref_status;
497 }
builtin/stash.c
+5 -2
@@ -1727,6 +1727,7 @@ static int push_stash(int argc, const char **argv, const char *prefix,
1727 OPT_PATHSPEC_FILE_NUL(&pathspec_file_nul),
1728 OPT_END()
1729 };
1730 + int ret;
1731
1732 if (argc) {
1733 force_assume = !strcmp(argv[0], "-p");
@@ -1766,8 +1767,10 @@ static int push_stash(int argc, const char **argv, const char *prefix,
1767 die(_("the option '%s' requires '%s'"), "--pathspec-file-nul", "--pathspec-from-file");
1768 }
1769
1769 - return do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,
1770 - include_untracked, only_staged);
1770 + ret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode,
1771 + include_untracked, only_staged);
1772 + clear_pathspec(&ps);
1773 + return ret;
1774 }
1775
1776 static int push_stash_unassumed(int argc, const char **argv, const char *prefix)
t/t5001-archive-attr.sh
+1
@@ -3,6 +3,7 @@
3 test_description='git archive attribute tests'
4
5 TEST_CREATE_REPO_NO_TEMPLATE=1
6 +TEST_PASSES_SANITIZE_LEAK=true
7 . ./test-lib.sh
8
9 SUBSTFORMAT='%H (%h)%n'
t/t5004-archive-corner-cases.sh
+2
@@ -1,6 +1,8 @@
1 #!/bin/sh
2
3 test_description='test corner cases of git-archive'
4 +
5 +TEST_PASSES_SANITIZE_LEAK=true
6 . ./test-lib.sh
7
8 # the 10knuls.tar file is used to test for an empty git generated tar
t/t7105-reset-patch.sh
+2
@@ -1,6 +1,8 @@
1 #!/bin/sh
2
3 test_description='git reset --patch'
4 +
5 +TEST_PASSES_SANITIZE_LEAK=true
6 . ./lib-patch-mode.sh
7
8 test_expect_success PERL 'setup' '
t/t7106-reset-unborn-branch.sh
+2
@@ -1,6 +1,8 @@
1 #!/bin/sh
2
3 test_description='git reset should work on unborn branch'
4 +
5 +TEST_PASSES_SANITIZE_LEAK=true
6 . ./test-lib.sh
7
8 test_expect_success 'setup' '
t/t7107-reset-pathspec-file.sh
+1
@@ -2,6 +2,7 @@
2
3 test_description='reset --pathspec-from-file'
4
5 +TEST_PASSES_SANITIZE_LEAK=true
6 . ./test-lib.sh
7
8 test_tick
t/t7301-clean-interactive.sh
+1
@@ -2,6 +2,7 @@
2
3 test_description='git clean -i basic tests'
4
5 +TEST_PASSES_SANITIZE_LEAK=true
6 . ./test-lib.sh
7 . "$TEST_DIRECTORY"/lib-terminal.sh
8