]> git.ipfire.org Git - thirdparty/git.git/commitdiff
dir: fix off by one errors for ignored and untracked entries
authorPatrick Steinhardt <ps@pks.im>
Thu, 26 Sep 2024 11:46:24 +0000 (13:46 +0200)
committerJunio C Hamano <gitster@pobox.com>
Fri, 27 Sep 2024 15:25:35 +0000 (08:25 -0700)
In `treat_directory()` we perform some logic to handle ignored and
untracked entries. When populating a directory with entries we first
save the current number of ignored/untracked entries and then populate
new entries at the end of our arrays that keep track of those entries.
When we figure out that all entries have been ignored/are untracked we
then remove this tail of entries from those vectors again. But there is
an off by one error in both paths that causes us to not free the first
ignored and untracked entries, respectively.

Fix these off-by-one errors to plug the resulting leak. While at it,
massage the code a bit to match our modern code style.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
dir.c
t/t3011-common-prefixes-and-directory-traversal.sh
t/t7061-wtstatus-ignore.sh
t/t7521-ignored-mode.sh

diff --git a/dir.c b/dir.c
index 5a23376bdaec3a7811677e7ca83e76ababa60a52..787bcb7a1a4f9a3a70bd20062d0bd792b98b5311 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -2135,8 +2135,7 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
                         */
                        state = path_none;
                } else {
-                       int i;
-                       for (i = old_ignored_nr + 1; i<dir->ignored_nr; ++i)
+                       for (int i = old_ignored_nr; i < dir->ignored_nr; i++)
                                FREE_AND_NULL(dir->ignored[i]);
                        dir->ignored_nr = old_ignored_nr;
                }
@@ -2148,8 +2147,7 @@ static enum path_treatment treat_directory(struct dir_struct *dir,
         */
        if ((dir->flags & DIR_SHOW_IGNORED_TOO) &&
            !(dir->flags & DIR_KEEP_UNTRACKED_CONTENTS)) {
-               int i;
-               for (i = old_untracked_nr + 1; i<dir->nr; ++i)
+               for (int i = old_untracked_nr; i < dir->nr; i++)
                        FREE_AND_NULL(dir->entries[i]);
                dir->nr = old_untracked_nr;
        }
index 3da5b2b6e795ec4587608ead8bc10abf0c6d9039..69e44c387fa83c576e80854424da694c8afa299c 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='directory traversal handling, especially with common prefixes'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup' '
index 2f9bea9793cec8b2900c35b3add315b67192a882..64145a05b1fd4ea1b75844a7e3690b790753c30c 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='git-status ignored files'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 cat >expected <<\EOF
index a88b02b06ed34234abfb3aa3131dd31a7d364141..edce10f998eecb9154f6188f3a6f3747fcfe56ed 100755 (executable)
@@ -2,6 +2,7 @@
 
 test_description='git status ignored modes'
 
+TEST_PASSES_SANITIZE_LEAK=true
 . ./test-lib.sh
 
 test_expect_success 'setup initial commit and ignore file' '