]> git.ipfire.org Git - thirdparty/git.git/commitdiff
ls-files: fix a trivial dir_clear() leak
authorÆvar Arnfjörð Bjarmason <avarab@gmail.com>
Thu, 7 Oct 2021 10:01:35 +0000 (12:01 +0200)
committerJunio C Hamano <gitster@pobox.com>
Thu, 7 Oct 2021 22:40:15 +0000 (15:40 -0700)
Fix an edge case that was missed when the dir_clear() call was added
in eceba532141 (dir: fix problematic API to avoid memory leaks,
2020-08-18), we need to also clean up when we're about to exit with
non-zero.

That commit says, on the topic of the dir_clear() API and UNLEAK():

    [...]two of them clearly thought about leaks since they had an
    UNLEAK(dir) directive, which to me suggests that the method to
    free the data was too unclear.

I think that 0e5bba53af7 (add UNLEAK annotation for reducing leak
false positives, 2017-09-08) which added the UNLEAK() makes it clear
that that wasn't the case, rather it was the desire to avoid the
complexity of freeing the memory at the end of the program.

This does add a bit of complexity, but I think it's worth it to just
fix these leaks when it's easy in built-ins. It allows them to serve
as canaries for underlying APIs that shouldn't be leaking, it
encourages us to make those freeing APIs nicer for all their users,
and it prevents other leaking regressions by being able to mark the
entire test as TEST_PASSES_SANITIZE_LEAK=true.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/ls-files.c
t/t3005-ls-files-relative.sh
t/t3020-ls-files-error-unmatch.sh
t/t3700-add.sh
t/t7104-reset-hard.sh

index a2000ed6bf2578ae248be18cb00623eb2b8d1fae..fcc685947f904e7a51a39c744210cdf98acc8cd4 100644 (file)
@@ -672,6 +672,7 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
                         N_("suppress duplicate entries")),
                OPT_END()
        };
+       int ret = 0;
 
        if (argc == 2 && !strcmp(argv[1], "-h"))
                usage_with_options(ls_files_usage, builtin_ls_files_options);
@@ -775,16 +776,12 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
        if (show_resolve_undo)
                show_ru_info(the_repository->index);
 
-       if (ps_matched) {
-               int bad;
-               bad = report_path_error(ps_matched, &pathspec);
-               if (bad)
-                       fprintf(stderr, "Did you forget to 'git add'?\n");
-
-               return bad ? 1 : 0;
+       if (ps_matched && report_path_error(ps_matched, &pathspec)) {
+               fprintf(stderr, "Did you forget to 'git add'?\n");
+               ret = 1;
        }
 
        dir_clear(&dir);
        free(max_prefix);
-       return 0;
+       return ret;
 }
index 727e9ae1a449ee4f105fe234b5041c6fbc397b45..6ba8b589cd00d3ad401f4018dc0eed7be1b54e05 100755 (executable)
@@ -5,6 +5,7 @@ test_description='ls-files tests with relative paths
 This test runs git ls-files with various relative path arguments.
 '
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'prepare' '
index 124e73b8e601ed3c714fe2857d2b227ee04e2ffc..2cbcbc0721b926dc7117ba680af7002466ed24a2 100755 (executable)
@@ -9,6 +9,8 @@ This test runs git ls-files --error-unmatch to ensure it correctly
 returns an error when a non-existent path is provided on the command
 line.
 '
+
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup' '
index 4086e1ebbc97f1220669a2a3236b255b6c20ce95..283a66955d6dbb8415697a8a911effa6f291f8e9 100755 (executable)
@@ -5,6 +5,7 @@
 
 test_description='Test of git add, including the -- option.'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 # Test the file mode "$1" of the file "$2" in the index.
index 7948ec392b3599a3884d97ae21f5deece84e638c..cf9697eba9a6aeb9579abe5b7b97b400aca8c7d0 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='reset --hard unmerged'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success setup '