• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2011 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "util.h"
16 
17 #include "test.h"
18 
19 namespace {
20 
CanonicalizePath(string * path,string * err)21 bool CanonicalizePath(string* path, string* err) {
22   uint64_t unused;
23   return ::CanonicalizePath(path, &unused, err);
24 }
25 
26 }  // namespace
27 
TEST(CanonicalizePath,PathSamples)28 TEST(CanonicalizePath, PathSamples) {
29   string path;
30   string err;
31 
32   EXPECT_FALSE(CanonicalizePath(&path, &err));
33   EXPECT_EQ("empty path", err);
34 
35   path = "foo.h"; err = "";
36   EXPECT_TRUE(CanonicalizePath(&path, &err));
37   EXPECT_EQ("foo.h", path);
38 
39   path = "./foo.h";
40   EXPECT_TRUE(CanonicalizePath(&path, &err));
41   EXPECT_EQ("foo.h", path);
42 
43   path = "./foo/./bar.h";
44   EXPECT_TRUE(CanonicalizePath(&path, &err));
45   EXPECT_EQ("foo/bar.h", path);
46 
47   path = "./x/foo/../bar.h";
48   EXPECT_TRUE(CanonicalizePath(&path, &err));
49   EXPECT_EQ("x/bar.h", path);
50 
51   path = "./x/foo/../../bar.h";
52   EXPECT_TRUE(CanonicalizePath(&path, &err));
53   EXPECT_EQ("bar.h", path);
54 
55   path = "foo//bar";
56   EXPECT_TRUE(CanonicalizePath(&path, &err));
57   EXPECT_EQ("foo/bar", path);
58 
59   path = "foo//.//..///bar";
60   EXPECT_TRUE(CanonicalizePath(&path, &err));
61   EXPECT_EQ("bar", path);
62 
63   path = "./x/../foo/../../bar.h";
64   EXPECT_TRUE(CanonicalizePath(&path, &err));
65   EXPECT_EQ("../bar.h", path);
66 
67   path = "foo/./.";
68   EXPECT_TRUE(CanonicalizePath(&path, &err));
69   EXPECT_EQ("foo", path);
70 
71   path = "foo/bar/..";
72   EXPECT_TRUE(CanonicalizePath(&path, &err));
73   EXPECT_EQ("foo", path);
74 
75   path = "foo/.hidden_bar";
76   EXPECT_TRUE(CanonicalizePath(&path, &err));
77   EXPECT_EQ("foo/.hidden_bar", path);
78 
79   path = "/foo";
80   EXPECT_TRUE(CanonicalizePath(&path, &err));
81   EXPECT_EQ("/foo", path);
82 
83   path = "//foo";
84   EXPECT_TRUE(CanonicalizePath(&path, &err));
85 #ifdef _WIN32
86   EXPECT_EQ("//foo", path);
87 #else
88   EXPECT_EQ("/foo", path);
89 #endif
90 
91   path = "/";
92   EXPECT_TRUE(CanonicalizePath(&path, &err));
93   EXPECT_EQ("", path);
94 
95   path = "/foo/..";
96   EXPECT_TRUE(CanonicalizePath(&path, &err));
97   EXPECT_EQ("", path);
98 
99   path = ".";
100   EXPECT_TRUE(CanonicalizePath(&path, &err));
101   EXPECT_EQ(".", path);
102 
103   path = "./.";
104   EXPECT_TRUE(CanonicalizePath(&path, &err));
105   EXPECT_EQ(".", path);
106 
107   path = "foo/..";
108   EXPECT_TRUE(CanonicalizePath(&path, &err));
109   EXPECT_EQ(".", path);
110 }
111 
112 #ifdef _WIN32
TEST(CanonicalizePath,PathSamplesWindows)113 TEST(CanonicalizePath, PathSamplesWindows) {
114   string path;
115   string err;
116 
117   EXPECT_FALSE(CanonicalizePath(&path, &err));
118   EXPECT_EQ("empty path", err);
119 
120   path = "foo.h"; err = "";
121   EXPECT_TRUE(CanonicalizePath(&path, &err));
122   EXPECT_EQ("foo.h", path);
123 
124   path = ".\\foo.h";
125   EXPECT_TRUE(CanonicalizePath(&path, &err));
126   EXPECT_EQ("foo.h", path);
127 
128   path = ".\\foo\\.\\bar.h";
129   EXPECT_TRUE(CanonicalizePath(&path, &err));
130   EXPECT_EQ("foo/bar.h", path);
131 
132   path = ".\\x\\foo\\..\\bar.h";
133   EXPECT_TRUE(CanonicalizePath(&path, &err));
134   EXPECT_EQ("x/bar.h", path);
135 
136   path = ".\\x\\foo\\..\\..\\bar.h";
137   EXPECT_TRUE(CanonicalizePath(&path, &err));
138   EXPECT_EQ("bar.h", path);
139 
140   path = "foo\\\\bar";
141   EXPECT_TRUE(CanonicalizePath(&path, &err));
142   EXPECT_EQ("foo/bar", path);
143 
144   path = "foo\\\\.\\\\..\\\\\\bar";
145   EXPECT_TRUE(CanonicalizePath(&path, &err));
146   EXPECT_EQ("bar", path);
147 
148   path = ".\\x\\..\\foo\\..\\..\\bar.h";
149   EXPECT_TRUE(CanonicalizePath(&path, &err));
150   EXPECT_EQ("../bar.h", path);
151 
152   path = "foo\\.\\.";
153   EXPECT_TRUE(CanonicalizePath(&path, &err));
154   EXPECT_EQ("foo", path);
155 
156   path = "foo\\bar\\..";
157   EXPECT_TRUE(CanonicalizePath(&path, &err));
158   EXPECT_EQ("foo", path);
159 
160   path = "foo\\.hidden_bar";
161   EXPECT_TRUE(CanonicalizePath(&path, &err));
162   EXPECT_EQ("foo/.hidden_bar", path);
163 
164   path = "\\foo";
165   EXPECT_TRUE(CanonicalizePath(&path, &err));
166   EXPECT_EQ("/foo", path);
167 
168   path = "\\\\foo";
169   EXPECT_TRUE(CanonicalizePath(&path, &err));
170   EXPECT_EQ("//foo", path);
171 
172   path = "\\";
173   EXPECT_TRUE(CanonicalizePath(&path, &err));
174   EXPECT_EQ("", path);
175 }
176 
TEST(CanonicalizePath,SlashTracking)177 TEST(CanonicalizePath, SlashTracking) {
178   string path;
179   string err;
180   uint64_t slash_bits;
181 
182   path = "foo.h"; err = "";
183   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
184   EXPECT_EQ("foo.h", path);
185   EXPECT_EQ(0, slash_bits);
186 
187   path = "a\\foo.h";
188   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
189   EXPECT_EQ("a/foo.h", path);
190   EXPECT_EQ(1, slash_bits);
191 
192   path = "a/bcd/efh\\foo.h";
193   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
194   EXPECT_EQ("a/bcd/efh/foo.h", path);
195   EXPECT_EQ(4, slash_bits);
196 
197   path = "a\\bcd/efh\\foo.h";
198   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
199   EXPECT_EQ("a/bcd/efh/foo.h", path);
200   EXPECT_EQ(5, slash_bits);
201 
202   path = "a\\bcd\\efh\\foo.h";
203   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
204   EXPECT_EQ("a/bcd/efh/foo.h", path);
205   EXPECT_EQ(7, slash_bits);
206 
207   path = "a/bcd/efh/foo.h";
208   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
209   EXPECT_EQ("a/bcd/efh/foo.h", path);
210   EXPECT_EQ(0, slash_bits);
211 
212   path = "a\\./efh\\foo.h";
213   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
214   EXPECT_EQ("a/efh/foo.h", path);
215   EXPECT_EQ(3, slash_bits);
216 
217   path = "a\\../efh\\foo.h";
218   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
219   EXPECT_EQ("efh/foo.h", path);
220   EXPECT_EQ(1, slash_bits);
221 
222   path = "a\\b\\c\\d\\e\\f\\g\\foo.h";
223   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
224   EXPECT_EQ("a/b/c/d/e/f/g/foo.h", path);
225   EXPECT_EQ(127, slash_bits);
226 
227   path = "a\\b\\c\\..\\..\\..\\g\\foo.h";
228   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
229   EXPECT_EQ("g/foo.h", path);
230   EXPECT_EQ(1, slash_bits);
231 
232   path = "a\\b/c\\../../..\\g\\foo.h";
233   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
234   EXPECT_EQ("g/foo.h", path);
235   EXPECT_EQ(1, slash_bits);
236 
237   path = "a\\b/c\\./../..\\g\\foo.h";
238   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
239   EXPECT_EQ("a/g/foo.h", path);
240   EXPECT_EQ(3, slash_bits);
241 
242   path = "a\\b/c\\./../..\\g/foo.h";
243   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
244   EXPECT_EQ("a/g/foo.h", path);
245   EXPECT_EQ(1, slash_bits);
246 
247   path = "a\\\\\\foo.h";
248   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
249   EXPECT_EQ("a/foo.h", path);
250   EXPECT_EQ(1, slash_bits);
251 
252   path = "a/\\\\foo.h";
253   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
254   EXPECT_EQ("a/foo.h", path);
255   EXPECT_EQ(0, slash_bits);
256 
257   path = "a\\//foo.h";
258   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
259   EXPECT_EQ("a/foo.h", path);
260   EXPECT_EQ(1, slash_bits);
261 }
262 
TEST(CanonicalizePath,CanonicalizeNotExceedingLen)263 TEST(CanonicalizePath, CanonicalizeNotExceedingLen) {
264   // Make sure searching \/ doesn't go past supplied len.
265   char buf[] = "foo/bar\\baz.h\\";  // Last \ past end.
266   uint64_t slash_bits;
267   string err;
268   size_t size = 13;
269   EXPECT_TRUE(::CanonicalizePath(buf, &size, &slash_bits, &err));
270   EXPECT_EQ(0, strncmp("foo/bar/baz.h", buf, size));
271   EXPECT_EQ(2, slash_bits);  // Not including the trailing one.
272 }
273 
TEST(CanonicalizePath,TooManyComponents)274 TEST(CanonicalizePath, TooManyComponents) {
275   string path;
276   string err;
277   uint64_t slash_bits;
278 
279   // 64 is OK.
280   path = "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./"
281          "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./x.h";
282   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
283   EXPECT_EQ(slash_bits, 0x0);
284 
285   // Backslashes version.
286   path =
287       "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
288       "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
289       "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
290       "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\x.h";
291 
292   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
293   EXPECT_EQ(slash_bits, 0xffffffff);
294 
295   // 65 is OK if #component is less than 60 after path canonicalization.
296   err = "";
297   path = "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./"
298          "a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./a/./x/y.h";
299   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
300   EXPECT_EQ(slash_bits, 0x0);
301 
302   // Backslashes version.
303   err = "";
304   path =
305       "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
306       "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
307       "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\"
308       "a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\a\\.\\x\\y.h";
309   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
310   EXPECT_EQ(slash_bits, 0x1ffffffff);
311 
312 
313   // 59 after canonicalization is OK.
314   err = "";
315   path = "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/"
316          "a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/a/x/y.h";
317   EXPECT_EQ(58, std::count(path.begin(), path.end(), '/'));
318   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
319   EXPECT_EQ(slash_bits, 0x0);
320 
321   // Backslashes version.
322   err = "";
323   path =
324       "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
325       "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
326       "a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\a\\"
327       "a\\a\\a\\a\\a\\a\\a\\a\\a\\x\\y.h";
328   EXPECT_EQ(58, std::count(path.begin(), path.end(), '\\'));
329   EXPECT_TRUE(CanonicalizePath(&path, &slash_bits, &err));
330   EXPECT_EQ(slash_bits, 0x3ffffffffffffff);
331 }
332 #endif
333 
TEST(CanonicalizePath,UpDir)334 TEST(CanonicalizePath, UpDir) {
335   string path, err;
336   path = "../../foo/bar.h";
337   EXPECT_TRUE(CanonicalizePath(&path, &err));
338   EXPECT_EQ("../../foo/bar.h", path);
339 
340   path = "test/../../foo/bar.h";
341   EXPECT_TRUE(CanonicalizePath(&path, &err));
342   EXPECT_EQ("../foo/bar.h", path);
343 }
344 
TEST(CanonicalizePath,AbsolutePath)345 TEST(CanonicalizePath, AbsolutePath) {
346   string path = "/usr/include/stdio.h";
347   string err;
348   EXPECT_TRUE(CanonicalizePath(&path, &err));
349   EXPECT_EQ("/usr/include/stdio.h", path);
350 }
351 
TEST(CanonicalizePath,NotNullTerminated)352 TEST(CanonicalizePath, NotNullTerminated) {
353   string path;
354   string err;
355   size_t len;
356   uint64_t unused;
357 
358   path = "foo/. bar/.";
359   len = strlen("foo/.");  // Canonicalize only the part before the space.
360   EXPECT_TRUE(CanonicalizePath(&path[0], &len, &unused, &err));
361   EXPECT_EQ(strlen("foo"), len);
362   EXPECT_EQ("foo/. bar/.", string(path));
363 
364   path = "foo/../file bar/.";
365   len = strlen("foo/../file");
366   EXPECT_TRUE(CanonicalizePath(&path[0], &len, &unused, &err));
367   EXPECT_EQ(strlen("file"), len);
368   EXPECT_EQ("file ./file bar/.", string(path));
369 }
370 
TEST(PathEscaping,TortureTest)371 TEST(PathEscaping, TortureTest) {
372   string result;
373 
374   GetWin32EscapedString("foo bar\\\"'$@d!st!c'\\path'\\", &result);
375   EXPECT_EQ("\"foo bar\\\\\\\"'$@d!st!c'\\path'\\\\\"", result);
376   result.clear();
377 
378   GetShellEscapedString("foo bar\"/'$@d!st!c'/path'", &result);
379   EXPECT_EQ("'foo bar\"/'\\''$@d!st!c'\\''/path'\\'''", result);
380 }
381 
TEST(PathEscaping,SensiblePathsAreNotNeedlesslyEscaped)382 TEST(PathEscaping, SensiblePathsAreNotNeedlesslyEscaped) {
383   const char* path = "some/sensible/path/without/crazy/characters.c++";
384   string result;
385 
386   GetWin32EscapedString(path, &result);
387   EXPECT_EQ(path, result);
388   result.clear();
389 
390   GetShellEscapedString(path, &result);
391   EXPECT_EQ(path, result);
392 }
393 
TEST(PathEscaping,SensibleWin32PathsAreNotNeedlesslyEscaped)394 TEST(PathEscaping, SensibleWin32PathsAreNotNeedlesslyEscaped) {
395   const char* path = "some\\sensible\\path\\without\\crazy\\characters.c++";
396   string result;
397 
398   GetWin32EscapedString(path, &result);
399   EXPECT_EQ(path, result);
400 }
401 
TEST(StripAnsiEscapeCodes,EscapeAtEnd)402 TEST(StripAnsiEscapeCodes, EscapeAtEnd) {
403   string stripped = StripAnsiEscapeCodes("foo\33");
404   EXPECT_EQ("foo", stripped);
405 
406   stripped = StripAnsiEscapeCodes("foo\33[");
407   EXPECT_EQ("foo", stripped);
408 }
409 
TEST(StripAnsiEscapeCodes,StripColors)410 TEST(StripAnsiEscapeCodes, StripColors) {
411   // An actual clang warning.
412   string input = "\33[1maffixmgr.cxx:286:15: \33[0m\33[0;1;35mwarning: "
413                  "\33[0m\33[1musing the result... [-Wparentheses]\33[0m";
414   string stripped = StripAnsiEscapeCodes(input);
415   EXPECT_EQ("affixmgr.cxx:286:15: warning: using the result... [-Wparentheses]",
416             stripped);
417 }
418 
TEST(ElideMiddle,NothingToElide)419 TEST(ElideMiddle, NothingToElide) {
420   string input = "Nothing to elide in this short string.";
421   EXPECT_EQ(input, ElideMiddle(input, 80));
422   EXPECT_EQ(input, ElideMiddle(input, 38));
423   EXPECT_EQ("", ElideMiddle(input, 0));
424   EXPECT_EQ(".", ElideMiddle(input, 1));
425   EXPECT_EQ("..", ElideMiddle(input, 2));
426   EXPECT_EQ("...", ElideMiddle(input, 3));
427 }
428 
TEST(ElideMiddle,ElideInTheMiddle)429 TEST(ElideMiddle, ElideInTheMiddle) {
430   string input = "01234567890123456789";
431   string elided = ElideMiddle(input, 10);
432   EXPECT_EQ("012...789", elided);
433   EXPECT_EQ("01234567...23456789", ElideMiddle(input, 19));
434 }
435