@matheusbsbs / matheus-bagliano / commits / 452efd11fb
Fork 0

t3011: demonstrate directory traversal failures

Add several tests demonstrating directory traversal failures of various sorts in dir.c (and one similar looking test that turns out to be a git_fnmatch bug). A lot of these tests look like near duplicates of each other, but an optimization path in dir.c to pre-descend into a common prefix and the specialized treatment of trailing slashes in dir.c mean the tiny differences are sometimes important and potentially cause different codepaths to be explored. Of the 7 failing tests, 2 are new to git-2.24.0 (tweaked by side effects of the en/clean-nested-with-ignored-topic); the other 5 also failed under git-2.23.0 and earlier. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Dec 10, 2019 at 20:00 UTC 452efd11fbf607ad12854edf1488112a7e4790d2
1 file changed +209
t/t3011-common-prefixes-and-directory-traversal.sh new
+209
@@ -0,0 +1,209 @@
1 +#!/bin/sh
2 +
3 +test_description='directory traversal handling, especially with common prefixes'
4 +
5 +. ./test-lib.sh
6 +
7 +test_expect_success 'setup' '
8 + test_commit hello &&
9 +
10 + >empty &&
11 + mkdir untracked_dir &&
12 + >untracked_dir/empty &&
13 + git init untracked_repo &&
14 + >untracked_repo/empty &&
15 +
16 + cat <<-EOF >.gitignore &&
17 + ignored
18 + an_ignored_dir/
19 + EOF
20 + mkdir an_ignored_dir &&
21 + mkdir an_untracked_dir &&
22 + >an_ignored_dir/ignored &&
23 + >an_ignored_dir/untracked &&
24 + >an_untracked_dir/ignored &&
25 + >an_untracked_dir/untracked
26 +'
27 +
28 +test_expect_success 'git ls-files -o shows the right entries' '
29 + cat <<-EOF >expect &&
30 + .gitignore
31 + actual
32 + an_ignored_dir/ignored
33 + an_ignored_dir/untracked
34 + an_untracked_dir/ignored
35 + an_untracked_dir/untracked
36 + empty
37 + expect
38 + untracked_dir/empty
39 + untracked_repo/
40 + EOF
41 + git ls-files -o >actual &&
42 + test_cmp expect actual
43 +'
44 +
45 +test_expect_success 'git ls-files -o --exclude-standard shows the right entries' '
46 + cat <<-EOF >expect &&
47 + .gitignore
48 + actual
49 + an_untracked_dir/untracked
50 + empty
51 + expect
52 + untracked_dir/empty
53 + untracked_repo/
54 + EOF
55 + git ls-files -o --exclude-standard >actual &&
56 + test_cmp expect actual
57 +'
58 +
59 +test_expect_success 'git ls-files -o untracked_dir recurses' '
60 + echo untracked_dir/empty >expect &&
61 + git ls-files -o untracked_dir >actual &&
62 + test_cmp expect actual
63 +'
64 +
65 +test_expect_success 'git ls-files -o untracked_dir/ recurses' '
66 + echo untracked_dir/empty >expect &&
67 + git ls-files -o untracked_dir/ >actual &&
68 + test_cmp expect actual
69 +'
70 +
71 +test_expect_success 'git ls-files -o --directory untracked_dir does not recurse' '
72 + echo untracked_dir/ >expect &&
73 + git ls-files -o --directory untracked_dir >actual &&
74 + test_cmp expect actual
75 +'
76 +
77 +test_expect_failure 'git ls-files -o --directory untracked_dir/ does not recurse' '
78 + echo untracked_dir/ >expect &&
79 + git ls-files -o --directory untracked_dir/ >actual &&
80 + test_cmp expect actual
81 +'
82 +
83 +test_expect_success 'git ls-files -o untracked_repo does not recurse' '
84 + echo untracked_repo/ >expect &&
85 + git ls-files -o untracked_repo >actual &&
86 + test_cmp expect actual
87 +'
88 +
89 +test_expect_failure 'git ls-files -o untracked_repo/ does not recurse' '
90 + echo untracked_repo/ >expect &&
91 + git ls-files -o untracked_repo/ >actual &&
92 + test_cmp expect actual
93 +'
94 +
95 +test_expect_failure 'git ls-files -o untracked_dir untracked_repo recurses into untracked_dir only' '
96 + cat <<-EOF >expect &&
97 + untracked_dir/empty
98 + untracked_repo/
99 + EOF
100 + git ls-files -o untracked_dir untracked_repo >actual &&
101 + test_cmp expect actual
102 +'
103 +
104 +test_expect_success 'git ls-files -o untracked_dir/ untracked_repo/ recurses into untracked_dir only' '
105 + cat <<-EOF >expect &&
106 + untracked_dir/empty
107 + untracked_repo/
108 + EOF
109 + git ls-files -o untracked_dir/ untracked_repo/ >actual &&
110 + test_cmp expect actual
111 +'
112 +
113 +test_expect_failure 'git ls-files -o --directory untracked_dir untracked_repo does not recurse' '
114 + cat <<-EOF >expect &&
115 + untracked_dir/
116 + untracked_repo/
117 + EOF
118 + git ls-files -o --directory untracked_dir untracked_repo >actual &&
119 + test_cmp expect actual
120 +'
121 +
122 +test_expect_success 'git ls-files -o --directory untracked_dir/ untracked_repo/ does not recurse' '
123 + cat <<-EOF >expect &&
124 + untracked_dir/
125 + untracked_repo/
126 + EOF
127 + git ls-files -o --directory untracked_dir/ untracked_repo/ >actual &&
128 + test_cmp expect actual
129 +'
130 +
131 +test_expect_success 'git ls-files -o .git shows nothing' '
132 + git ls-files -o .git >actual &&
133 + test_must_be_empty actual
134 +'
135 +
136 +test_expect_failure 'git ls-files -o .git/ shows nothing' '
137 + git ls-files -o .git/ >actual &&
138 + test_must_be_empty actual
139 +'
140 +
141 +test_expect_success FUNNYNAMES 'git ls-files -o untracked_* recurses appropriately' '
142 + mkdir "untracked_*" &&
143 + >"untracked_*/empty" &&
144 +
145 + cat <<-EOF >expect &&
146 + untracked_*/empty
147 + untracked_dir/empty
148 + untracked_repo/
149 + EOF
150 + git ls-files -o "untracked_*" >actual &&
151 + test_cmp expect actual
152 +'
153 +
154 +# It turns out fill_directory returns the right paths, but ls-files' post-call
155 +# filtering in show_dir_entry() via calling dir_path_match() which ends up
156 +# in git_fnmatch() has logic for PATHSPEC_ONESTAR that assumes the pathspec
157 +# must match the full path; it doesn't check it for matching a leading
158 +# directory.
159 +test_expect_failure FUNNYNAMES 'git ls-files -o untracked_*/ recurses appropriately' '
160 + cat <<-EOF >expect &&
161 + untracked_*/empty
162 + untracked_dir/empty
163 + untracked_repo/
164 + EOF
165 + git ls-files -o "untracked_*/" >actual &&
166 + test_cmp expect actual
167 +'
168 +
169 +test_expect_success FUNNYNAMES 'git ls-files -o --directory untracked_* does not recurse' '
170 + cat <<-EOF >expect &&
171 + untracked_*/
172 + untracked_dir/
173 + untracked_repo/
174 + EOF
175 + git ls-files -o --directory "untracked_*" >actual &&
176 + test_cmp expect actual
177 +'
178 +
179 +test_expect_success FUNNYNAMES 'git ls-files -o --directory untracked_*/ does not recurse' '
180 + cat <<-EOF >expect &&
181 + untracked_*/
182 + untracked_dir/
183 + untracked_repo/
184 + EOF
185 + git ls-files -o --directory "untracked_*/" >actual &&
186 + test_cmp expect actual
187 +'
188 +
189 +test_expect_success 'git ls-files -o consistent between one or two dirs' '
190 + git ls-files -o --exclude-standard an_ignored_dir/ an_untracked_dir/ >tmp &&
191 + ! grep ^an_ignored_dir/ tmp >expect &&
192 + git ls-files -o --exclude-standard an_ignored_dir/ >actual &&
193 + test_cmp expect actual
194 +'
195 +
196 +# ls-files doesn't have a way to request showing both untracked and ignored
197 +# files at the same time, so use `git status --ignored`
198 +test_expect_failure 'git status --ignored shows same files under dir with or without pathspec' '
199 + cat <<-EOF >expect &&
200 + ?? an_untracked_dir/
201 + !! an_untracked_dir/ignored
202 + EOF
203 + git status --porcelain --ignored >output &&
204 + grep an_untracked_dir output >expect &&
205 + git status --porcelain --ignored an_untracked_dir/ >actual &&
206 + test_cmp expect actual
207 +'
208 +
209 +test_done