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