]>
Commit | Line | Data |
---|---|---|
0383bbb9 JK |
1 | #!/bin/sh |
2 | ||
3 | test_description='check handling of .. in submodule names | |
4 | ||
5 | Exercise the name-checking function on a variety of names, and then give a | |
6 | real-world setup that confirms we catch this in practice. | |
7 | ' | |
8 | . ./test-lib.sh | |
73c3f0f7 | 9 | . "$TEST_DIRECTORY"/lib-pack.sh |
0383bbb9 JK |
10 | |
11 | test_expect_success 'check names' ' | |
12 | cat >expect <<-\EOF && | |
13 | valid | |
14 | valid/with/paths | |
15 | EOF | |
16 | ||
17 | git submodule--helper check-name >actual <<-\EOF && | |
18 | valid | |
19 | valid/with/paths | |
20 | ||
21 | ../foo | |
22 | /../foo | |
23 | ..\foo | |
24 | \..\foo | |
25 | foo/.. | |
26 | foo/../ | |
27 | foo\.. | |
28 | foo\..\ | |
29 | foo/../bar | |
30 | EOF | |
31 | ||
32 | test_cmp expect actual | |
33 | ' | |
34 | ||
35 | test_expect_success 'create innocent subrepo' ' | |
36 | git init innocent && | |
37 | git -C innocent commit --allow-empty -m foo | |
38 | ' | |
39 | ||
40 | test_expect_success 'submodule add refuses invalid names' ' | |
41 | test_must_fail \ | |
42 | git submodule add --name ../../modules/evil "$PWD/innocent" evil | |
43 | ' | |
44 | ||
45 | test_expect_success 'add evil submodule' ' | |
46 | git submodule add "$PWD/innocent" evil && | |
47 | ||
48 | mkdir modules && | |
49 | cp -r .git/modules/evil modules && | |
50 | write_script modules/evil/hooks/post-checkout <<-\EOF && | |
51 | echo >&2 "RUNNING POST CHECKOUT" | |
52 | EOF | |
53 | ||
54 | git config -f .gitmodules submodule.evil.update checkout && | |
55 | git config -f .gitmodules --rename-section \ | |
56 | submodule.evil submodule.../../modules/evil && | |
57 | git add modules && | |
58 | git commit -am evil | |
59 | ' | |
60 | ||
61 | # This step seems like it shouldn't be necessary, since the payload is | |
62 | # contained entirely in the evil submodule. But due to the vagaries of the | |
63 | # submodule code, checking out the evil module will fail unless ".git/modules" | |
64 | # exists. Adding another submodule (with a name that sorts before "evil") is an | |
65 | # easy way to make sure this is the case in the victim clone. | |
66 | test_expect_success 'add other submodule' ' | |
67 | git submodule add "$PWD/innocent" another-module && | |
68 | git add another-module && | |
69 | git commit -am another | |
70 | ' | |
71 | ||
72 | test_expect_success 'clone evil superproject' ' | |
73 | git clone --recurse-submodules . victim >output 2>&1 && | |
74 | ! grep "RUNNING POST CHECKOUT" output | |
75 | ' | |
76 | ||
1995b5e0 JK |
77 | test_expect_success 'fsck detects evil superproject' ' |
78 | test_must_fail git fsck | |
79 | ' | |
80 | ||
6e328d6c JK |
81 | test_expect_success 'transfer.fsckObjects detects evil superproject (unpack)' ' |
82 | rm -rf dst.git && | |
83 | git init --bare dst.git && | |
84 | git -C dst.git config transfer.fsckObjects true && | |
85 | test_must_fail git push dst.git HEAD | |
86 | ' | |
87 | ||
73c3f0f7 JK |
88 | test_expect_success 'transfer.fsckObjects detects evil superproject (index)' ' |
89 | rm -rf dst.git && | |
90 | git init --bare dst.git && | |
91 | git -C dst.git config transfer.fsckObjects true && | |
92 | git -C dst.git config transfer.unpackLimit 1 && | |
93 | test_must_fail git push dst.git HEAD | |
94 | ' | |
95 | ||
96 | # Normally our packs contain commits followed by trees followed by blobs. This | |
97 | # reverses the order, which requires backtracking to find the context of a | |
98 | # blob. We'll start with a fresh gitmodules-only tree to make it simpler. | |
99 | test_expect_success 'create oddly ordered pack' ' | |
100 | git checkout --orphan odd && | |
101 | git rm -rf --cached . && | |
102 | git add .gitmodules && | |
103 | git commit -m odd && | |
104 | { | |
105 | pack_header 3 && | |
106 | pack_obj $(git rev-parse HEAD:.gitmodules) && | |
107 | pack_obj $(git rev-parse HEAD^{tree}) && | |
108 | pack_obj $(git rev-parse HEAD) | |
109 | } >odd.pack && | |
110 | pack_trailer odd.pack | |
111 | ' | |
112 | ||
113 | test_expect_success 'transfer.fsckObjects handles odd pack (unpack)' ' | |
114 | rm -rf dst.git && | |
115 | git init --bare dst.git && | |
116 | test_must_fail git -C dst.git unpack-objects --strict <odd.pack | |
117 | ' | |
118 | ||
119 | test_expect_success 'transfer.fsckObjects handles odd pack (index)' ' | |
120 | rm -rf dst.git && | |
121 | git init --bare dst.git && | |
122 | test_must_fail git -C dst.git index-pack --strict --stdin <odd.pack | |
123 | ' | |
124 | ||
368b4e59 JK |
125 | test_expect_success 'index-pack --strict works for non-repo pack' ' |
126 | rm -rf dst.git && | |
127 | git init --bare dst.git && | |
128 | cp odd.pack dst.git && | |
129 | test_must_fail git -C dst.git index-pack --strict odd.pack 2>output && | |
130 | # Make sure we fail due to bad gitmodules content, not because we | |
131 | # could not read the blob in the first place. | |
132 | grep gitmodulesName output | |
133 | ' | |
134 | ||
b7b1fca1 JK |
135 | test_expect_success 'fsck detects symlinked .gitmodules file' ' |
136 | git init symlink && | |
137 | ( | |
138 | cd symlink && | |
139 | ||
140 | # Make the tree directly to avoid index restrictions. | |
141 | # | |
142 | # Because symlinks store the target as a blob, choose | |
143 | # a pathname that could be parsed as a .gitmodules file | |
144 | # to trick naive non-symlink-aware checking. | |
145 | tricky="[foo]bar=true" && | |
146 | content=$(git hash-object -w ../.gitmodules) && | |
147 | target=$(printf "$tricky" | git hash-object -w --stdin) && | |
431acd2d JK |
148 | { |
149 | printf "100644 blob $content\t$tricky\n" && | |
150 | printf "120000 blob $target\t.gitmodules\n" | |
151 | } | git mktree && | |
b7b1fca1 JK |
152 | |
153 | # Check not only that we fail, but that it is due to the | |
154 | # symlink detector; this grep string comes from the config | |
155 | # variable name and will not be translated. | |
156 | test_must_fail git fsck 2>output && | |
674ba340 | 157 | test_i18ngrep gitmodulesSymlink output |
b7b1fca1 JK |
158 | ) |
159 | ' | |
160 | ||
47cc9131 JK |
161 | test_expect_success 'fsck detects non-blob .gitmodules' ' |
162 | git init non-blob && | |
163 | ( | |
164 | cd non-blob && | |
165 | ||
166 | # As above, make the funny tree directly to avoid index | |
167 | # restrictions. | |
168 | mkdir subdir && | |
169 | cp ../.gitmodules subdir/file && | |
170 | git add subdir/file && | |
171 | git commit -m ok && | |
172 | git ls-tree HEAD | sed s/subdir/.gitmodules/ | git mktree && | |
173 | ||
174 | test_must_fail git fsck 2>output && | |
674ba340 | 175 | test_i18ngrep gitmodulesBlob output |
47cc9131 JK |
176 | ) |
177 | ' | |
178 | ||
de6bd9e3 JK |
179 | test_expect_success 'fsck detects corrupt .gitmodules' ' |
180 | git init corrupt && | |
181 | ( | |
182 | cd corrupt && | |
183 | ||
184 | echo "[broken" >.gitmodules && | |
185 | git add .gitmodules && | |
186 | git commit -m "broken gitmodules" && | |
187 | ||
64eb14d3 | 188 | git fsck 2>output && |
674ba340 | 189 | test_i18ngrep gitmodulesParse output && |
de6bd9e3 JK |
190 | test_i18ngrep ! "bad config" output |
191 | ) | |
192 | ' | |
193 | ||
0060fd15 JS |
194 | test_expect_success MINGW 'prevent git~1 squatting on Windows' ' |
195 | git init squatting && | |
196 | ( | |
197 | cd squatting && | |
198 | mkdir a && | |
199 | touch a/..git && | |
200 | git add a/..git && | |
201 | test_tick && | |
202 | git commit -m initial && | |
203 | ||
204 | modules="$(test_write_lines \ | |
205 | "[submodule \"b.\"]" "url = ." "path = c" \ | |
206 | "[submodule \"b\"]" "url = ." "path = d\\\\a" | | |
207 | git hash-object -w --stdin)" && | |
208 | rev="$(git rev-parse --verify HEAD)" && | |
209 | hash="$(echo x | git hash-object -w --stdin)" && | |
224c7d70 JS |
210 | test_must_fail git update-index --add \ |
211 | --cacheinfo 160000,$rev,d\\a 2>err && | |
49e268e2 | 212 | test_i18ngrep "Invalid path" err && |
e1d911dd | 213 | git -c core.protectNTFS=false update-index --add \ |
0060fd15 JS |
214 | --cacheinfo 100644,$modules,.gitmodules \ |
215 | --cacheinfo 160000,$rev,c \ | |
216 | --cacheinfo 160000,$rev,d\\a \ | |
217 | --cacheinfo 100644,$hash,d./a/x \ | |
218 | --cacheinfo 100644,$hash,d./a/..git && | |
219 | test_tick && | |
224c7d70 | 220 | git -c core.protectNTFS=false commit -m "module" |
0060fd15 | 221 | ) && |
e1d911dd | 222 | test_must_fail git -c core.protectNTFS=false \ |
0060fd15 | 223 | clone --recurse-submodules squatting squatting-clone 2>err && |
d2c84dad | 224 | test_i18ngrep -e "directory not empty" -e "not an empty directory" err && |
0060fd15 JS |
225 | ! grep gitdir squatting-clone/d/a/git~2 |
226 | ' | |
227 | ||
a8dee3ca JS |
228 | test_expect_success 'git dirs of sibling submodules must not be nested' ' |
229 | git init nested && | |
230 | test_commit -C nested nested && | |
231 | ( | |
232 | cd nested && | |
233 | cat >.gitmodules <<-EOF && | |
234 | [submodule "hippo"] | |
235 | url = . | |
236 | path = thing1 | |
237 | [submodule "hippo/hooks"] | |
238 | url = . | |
239 | path = thing2 | |
240 | EOF | |
241 | git clone . thing1 && | |
242 | git clone . thing2 && | |
243 | git add .gitmodules thing1 thing2 && | |
244 | test_tick && | |
245 | git commit -m nested | |
246 | ) && | |
247 | test_must_fail git clone --recurse-submodules nested clone 2>err && | |
d9061ed9 | 248 | test_i18ngrep "is inside git dir" err |
a8dee3ca JS |
249 | ' |
250 | ||
0383bbb9 | 251 | test_done |