]>
Commit | Line | Data |
---|---|---|
cceae9a2 ET |
1 | |
2 | #include "clar_libgit2.h" | |
3 | #include "path.h" | |
4 | ||
5 | #ifdef GIT_WIN32 | |
6 | #include "win32/path_w32.h" | |
7 | #endif | |
8 | ||
9 | void test_utf8_to_utf16(const char *utf8_in, const wchar_t *utf16_expected) | |
10 | { | |
11 | #ifdef GIT_WIN32 | |
12 | git_win32_path path_utf16; | |
13 | int path_utf16len; | |
14 | ||
15 | cl_assert((path_utf16len = git_win32_path_from_utf8(path_utf16, utf8_in)) >= 0); | |
16 | cl_assert_equal_wcs(utf16_expected, path_utf16); | |
17 | cl_assert_equal_i(wcslen(utf16_expected), path_utf16len); | |
18 | #else | |
19 | GIT_UNUSED(utf8_in); | |
20 | GIT_UNUSED(utf16_expected); | |
21 | #endif | |
22 | } | |
23 | ||
66a70851 UG |
24 | void test_utf8_to_utf16_relative(const char* utf8_in, const wchar_t* utf16_expected) |
25 | { | |
26 | #ifdef GIT_WIN32 | |
27 | git_win32_path path_utf16; | |
28 | int path_utf16len; | |
29 | ||
30 | cl_assert((path_utf16len = git_win32_path_relative_from_utf8(path_utf16, utf8_in)) >= 0); | |
31 | cl_assert_equal_wcs(utf16_expected, path_utf16); | |
32 | cl_assert_equal_i(wcslen(utf16_expected), path_utf16len); | |
33 | #else | |
34 | GIT_UNUSED(utf8_in); | |
35 | GIT_UNUSED(utf16_expected); | |
36 | #endif | |
37 | } | |
38 | ||
cceae9a2 ET |
39 | void test_path_win32__utf8_to_utf16(void) |
40 | { | |
41 | #ifdef GIT_WIN32 | |
42 | test_utf8_to_utf16("C:\\", L"\\\\?\\C:\\"); | |
43 | test_utf8_to_utf16("c:\\", L"\\\\?\\c:\\"); | |
44 | test_utf8_to_utf16("C:/", L"\\\\?\\C:\\"); | |
45 | test_utf8_to_utf16("c:/", L"\\\\?\\c:\\"); | |
46 | #endif | |
47 | } | |
48 | ||
49 | void test_path_win32__removes_trailing_slash(void) | |
50 | { | |
51 | #ifdef GIT_WIN32 | |
52 | test_utf8_to_utf16("C:\\Foo\\", L"\\\\?\\C:\\Foo"); | |
53 | test_utf8_to_utf16("C:\\Foo\\\\", L"\\\\?\\C:\\Foo"); | |
54 | test_utf8_to_utf16("C:\\Foo\\\\", L"\\\\?\\C:\\Foo"); | |
55 | test_utf8_to_utf16("C:/Foo/", L"\\\\?\\C:\\Foo"); | |
56 | test_utf8_to_utf16("C:/Foo///", L"\\\\?\\C:\\Foo"); | |
57 | #endif | |
58 | } | |
59 | ||
60 | void test_path_win32__squashes_multiple_slashes(void) | |
61 | { | |
62 | #ifdef GIT_WIN32 | |
63 | test_utf8_to_utf16("C:\\\\Foo\\Bar\\\\Foobar", L"\\\\?\\C:\\Foo\\Bar\\Foobar"); | |
64 | test_utf8_to_utf16("C://Foo/Bar///Foobar", L"\\\\?\\C:\\Foo\\Bar\\Foobar"); | |
65 | #endif | |
66 | } | |
67 | ||
68 | void test_path_win32__unc(void) | |
69 | { | |
70 | #ifdef GIT_WIN32 | |
71 | test_utf8_to_utf16("\\\\server\\c$\\unc\\path", L"\\\\?\\UNC\\server\\c$\\unc\\path"); | |
72 | test_utf8_to_utf16("//server/git/style/unc/path", L"\\\\?\\UNC\\server\\git\\style\\unc\\path"); | |
73 | #endif | |
74 | } | |
75 | ||
76 | void test_path_win32__honors_max_path(void) | |
77 | { | |
78 | #ifdef GIT_WIN32 | |
79 | git_win32_path path_utf16; | |
80 | ||
81 | test_utf8_to_utf16("C:\\This path is 259 chars and is the max length in windows\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij", | |
82 | L"\\\\?\\C:\\This path is 259 chars and is the max length in windows\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij"); | |
83 | test_utf8_to_utf16("\\\\unc\\paths may also be 259 characters including the server\\123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij", | |
84 | L"\\\\?\\UNC\\unc\\paths may also be 259 characters including the server\\123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij"); | |
85 | ||
86 | cl_check_fail(git_win32_path_from_utf8(path_utf16, "C:\\This path is 260 chars and is sadly too long for windows\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij")); | |
87 | cl_check_fail(git_win32_path_from_utf8(path_utf16, "\\\\unc\\paths are also bound by 260 character restrictions\\including the server name portion\\bcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij")); | |
88 | #endif | |
89 | } | |
90 | ||
91 | void test_path_win32__dot_and_dotdot(void) | |
92 | { | |
93 | #ifdef GIT_WIN32 | |
94 | test_utf8_to_utf16("C:\\Foo\\..\\Foobar", L"\\\\?\\C:\\Foobar"); | |
95 | test_utf8_to_utf16("C:\\Foo\\Bar\\..\\Foobar", L"\\\\?\\C:\\Foo\\Foobar"); | |
96 | test_utf8_to_utf16("C:\\Foo\\Bar\\..\\Foobar\\..", L"\\\\?\\C:\\Foo"); | |
97 | test_utf8_to_utf16("C:\\Foobar\\..", L"\\\\?\\C:\\"); | |
98 | test_utf8_to_utf16("C:/Foo/Bar/../Foobar", L"\\\\?\\C:\\Foo\\Foobar"); | |
99 | test_utf8_to_utf16("C:/Foo/Bar/../Foobar/../Asdf/", L"\\\\?\\C:\\Foo\\Asdf"); | |
100 | test_utf8_to_utf16("C:/Foo/Bar/../Foobar/..", L"\\\\?\\C:\\Foo"); | |
101 | test_utf8_to_utf16("C:/Foo/..", L"\\\\?\\C:\\"); | |
102 | ||
103 | test_utf8_to_utf16("C:\\Foo\\Bar\\.\\Foobar", L"\\\\?\\C:\\Foo\\Bar\\Foobar"); | |
104 | test_utf8_to_utf16("C:\\.\\Foo\\.\\Bar\\.\\Foobar\\.\\", L"\\\\?\\C:\\Foo\\Bar\\Foobar"); | |
105 | test_utf8_to_utf16("C:/Foo/Bar/./Foobar", L"\\\\?\\C:\\Foo\\Bar\\Foobar"); | |
106 | test_utf8_to_utf16("C:/Foo/../Bar/./Foobar/../", L"\\\\?\\C:\\Bar"); | |
107 | ||
108 | test_utf8_to_utf16("C:\\Foo\\..\\..\\Bar", L"\\\\?\\C:\\Bar"); | |
109 | #endif | |
110 | } | |
111 | ||
112 | void test_path_win32__absolute_from_no_drive_letter(void) | |
113 | { | |
114 | #ifdef GIT_WIN32 | |
115 | test_utf8_to_utf16("\\Foo", L"\\\\?\\C:\\Foo"); | |
116 | test_utf8_to_utf16("\\Foo\\Bar", L"\\\\?\\C:\\Foo\\Bar"); | |
117 | test_utf8_to_utf16("/Foo/Bar", L"\\\\?\\C:\\Foo\\Bar"); | |
118 | #endif | |
119 | } | |
120 | ||
121 | void test_path_win32__absolute_from_relative(void) | |
122 | { | |
123 | #ifdef GIT_WIN32 | |
124 | char cwd_backup[MAX_PATH]; | |
125 | ||
126 | cl_must_pass(p_getcwd(cwd_backup, MAX_PATH)); | |
127 | cl_must_pass(p_chdir("C:/")); | |
128 | ||
129 | test_utf8_to_utf16("Foo", L"\\\\?\\C:\\Foo"); | |
130 | test_utf8_to_utf16("..\\..\\Foo", L"\\\\?\\C:\\Foo"); | |
131 | test_utf8_to_utf16("Foo\\..", L"\\\\?\\C:\\"); | |
132 | test_utf8_to_utf16("Foo\\..\\..", L"\\\\?\\C:\\"); | |
133 | test_utf8_to_utf16("", L"\\\\?\\C:\\"); | |
134 | ||
135 | cl_must_pass(p_chdir("C:/Windows")); | |
136 | ||
137 | test_utf8_to_utf16("Foo", L"\\\\?\\C:\\Windows\\Foo"); | |
138 | test_utf8_to_utf16("Foo\\Bar", L"\\\\?\\C:\\Windows\\Foo\\Bar"); | |
139 | test_utf8_to_utf16("..\\Foo", L"\\\\?\\C:\\Foo"); | |
140 | test_utf8_to_utf16("Foo\\..\\Bar", L"\\\\?\\C:\\Windows\\Bar"); | |
141 | test_utf8_to_utf16("", L"\\\\?\\C:\\Windows"); | |
142 | ||
143 | cl_must_pass(p_chdir(cwd_backup)); | |
144 | #endif | |
145 | } | |
146 | ||
66a70851 UG |
147 | void test_path_win32__keeps_relative(void) |
148 | { | |
149 | #ifdef GIT_WIN32 | |
150 | /* Relative paths stay relative */ | |
151 | test_utf8_to_utf16_relative("Foo", L"Foo"); | |
152 | test_utf8_to_utf16_relative("..\\..\\Foo", L"..\\..\\Foo"); | |
153 | test_utf8_to_utf16_relative("Foo\\..", L"Foo\\.."); | |
154 | test_utf8_to_utf16_relative("Foo\\..\\..", L"Foo\\..\\.."); | |
155 | test_utf8_to_utf16_relative("Foo\\Bar", L"Foo\\Bar"); | |
156 | test_utf8_to_utf16_relative("Foo\\..\\Bar", L"Foo\\..\\Bar"); | |
157 | test_utf8_to_utf16_relative("../../Foo", L"..\\..\\Foo"); | |
158 | test_utf8_to_utf16_relative("Foo/..", L"Foo\\.."); | |
159 | test_utf8_to_utf16_relative("Foo/../..", L"Foo\\..\\.."); | |
160 | test_utf8_to_utf16_relative("Foo/Bar", L"Foo\\Bar"); | |
161 | test_utf8_to_utf16_relative("Foo/../Bar", L"Foo\\..\\Bar"); | |
162 | test_utf8_to_utf16_relative("Foo/../Bar/", L"Foo\\..\\Bar\\"); | |
163 | test_utf8_to_utf16_relative("", L""); | |
164 | ||
165 | /* Absolute paths are canonicalized */ | |
166 | test_utf8_to_utf16_relative("\\Foo", L"\\\\?\\C:\\Foo"); | |
167 | test_utf8_to_utf16_relative("/Foo/Bar/", L"\\\\?\\C:\\Foo\\Bar"); | |
168 | test_utf8_to_utf16_relative("\\\\server\\c$\\unc\\path", L"\\\\?\\UNC\\server\\c$\\unc\\path"); | |
169 | #endif | |
170 | } | |
171 | ||
cceae9a2 | 172 | #ifdef GIT_WIN32 |
ac3d33df JK |
173 | static void test_canonicalize(const wchar_t *in, const wchar_t *expected) |
174 | { | |
cceae9a2 ET |
175 | git_win32_path canonical; |
176 | ||
177 | cl_assert(wcslen(in) < MAX_PATH); | |
178 | wcscpy(canonical, in); | |
179 | ||
180 | cl_must_pass(git_win32_path_canonicalize(canonical)); | |
181 | cl_assert_equal_wcs(expected, canonical); | |
ac3d33df JK |
182 | } |
183 | #endif | |
184 | ||
185 | static void test_remove_namespace(const wchar_t *in, const wchar_t *expected) | |
186 | { | |
187 | #ifdef GIT_WIN32 | |
188 | git_win32_path canonical; | |
189 | ||
190 | cl_assert(wcslen(in) < MAX_PATH); | |
191 | wcscpy(canonical, in); | |
192 | ||
193 | git_win32_path_remove_namespace(canonical, wcslen(in)); | |
194 | cl_assert_equal_wcs(expected, canonical); | |
cceae9a2 ET |
195 | #else |
196 | GIT_UNUSED(in); | |
197 | GIT_UNUSED(expected); | |
198 | #endif | |
199 | } | |
200 | ||
ac3d33df JK |
201 | void test_path_win32__remove_namespace(void) |
202 | { | |
203 | test_remove_namespace(L"\\\\?\\C:\\Temp\\Foo", L"C:\\Temp\\Foo"); | |
204 | test_remove_namespace(L"\\\\?\\C:\\", L"C:\\"); | |
205 | test_remove_namespace(L"\\\\?\\", L""); | |
206 | ||
207 | test_remove_namespace(L"\\??\\C:\\Temp\\Foo", L"C:\\Temp\\Foo"); | |
208 | test_remove_namespace(L"\\??\\C:\\", L"C:\\"); | |
209 | test_remove_namespace(L"\\??\\", L""); | |
210 | ||
211 | test_remove_namespace(L"\\\\?\\UNC\\server\\C$\\folder", L"\\\\server\\C$\\folder"); | |
212 | test_remove_namespace(L"\\\\?\\UNC\\server\\C$\\folder", L"\\\\server\\C$\\folder"); | |
213 | test_remove_namespace(L"\\\\?\\UNC\\server\\C$", L"\\\\server\\C$"); | |
214 | test_remove_namespace(L"\\\\?\\UNC\\server\\", L"\\\\server"); | |
215 | test_remove_namespace(L"\\\\?\\UNC\\server", L"\\\\server"); | |
216 | ||
217 | test_remove_namespace(L"\\??\\UNC\\server\\C$\\folder", L"\\\\server\\C$\\folder"); | |
218 | test_remove_namespace(L"\\??\\UNC\\server\\C$\\folder", L"\\\\server\\C$\\folder"); | |
219 | test_remove_namespace(L"\\??\\UNC\\server\\C$", L"\\\\server\\C$"); | |
220 | test_remove_namespace(L"\\??\\UNC\\server\\", L"\\\\server"); | |
221 | test_remove_namespace(L"\\??\\UNC\\server", L"\\\\server"); | |
222 | ||
223 | test_remove_namespace(L"\\\\server\\C$\\folder", L"\\\\server\\C$\\folder"); | |
224 | test_remove_namespace(L"\\\\server\\C$", L"\\\\server\\C$"); | |
225 | test_remove_namespace(L"\\\\server\\", L"\\\\server"); | |
226 | test_remove_namespace(L"\\\\server", L"\\\\server"); | |
227 | ||
228 | test_remove_namespace(L"C:\\Foo\\Bar", L"C:\\Foo\\Bar"); | |
229 | test_remove_namespace(L"C:\\", L"C:\\"); | |
230 | test_remove_namespace(L"", L""); | |
231 | ||
232 | } | |
233 | ||
cceae9a2 ET |
234 | void test_path_win32__canonicalize(void) |
235 | { | |
236 | #ifdef GIT_WIN32 | |
237 | test_canonicalize(L"C:\\Foo\\Bar", L"C:\\Foo\\Bar"); | |
238 | test_canonicalize(L"C:\\Foo\\", L"C:\\Foo"); | |
239 | test_canonicalize(L"C:\\Foo\\\\", L"C:\\Foo"); | |
240 | test_canonicalize(L"C:\\Foo\\..\\Bar", L"C:\\Bar"); | |
241 | test_canonicalize(L"C:\\Foo\\..\\..\\Bar", L"C:\\Bar"); | |
242 | test_canonicalize(L"C:\\Foo\\..\\..\\..\\..\\", L"C:\\"); | |
243 | test_canonicalize(L"C:/Foo/Bar", L"C:\\Foo\\Bar"); | |
244 | test_canonicalize(L"C:/", L"C:\\"); | |
245 | ||
cceae9a2 ET |
246 | test_canonicalize(L"\\\\?\\C:\\Foo\\Bar", L"\\\\?\\C:\\Foo\\Bar"); |
247 | test_canonicalize(L"\\\\?\\C:\\Foo\\Bar\\", L"\\\\?\\C:\\Foo\\Bar"); | |
248 | test_canonicalize(L"\\\\?\\C:\\\\Foo\\.\\Bar\\\\..\\", L"\\\\?\\C:\\Foo"); | |
249 | test_canonicalize(L"\\\\?\\C:\\\\", L"\\\\?\\C:\\"); | |
250 | test_canonicalize(L"//?/C:/", L"\\\\?\\C:\\"); | |
251 | test_canonicalize(L"//?/C:/../../Foo/", L"\\\\?\\C:\\Foo"); | |
252 | test_canonicalize(L"//?/C:/Foo/../../", L"\\\\?\\C:\\"); | |
253 | ||
254 | test_canonicalize(L"\\\\?\\UNC\\server\\C$\\folder", L"\\\\?\\UNC\\server\\C$\\folder"); | |
255 | test_canonicalize(L"\\\\?\\UNC\\server\\C$\\folder\\", L"\\\\?\\UNC\\server\\C$\\folder"); | |
256 | test_canonicalize(L"\\\\?\\UNC\\server\\C$\\folder\\", L"\\\\?\\UNC\\server\\C$\\folder"); | |
257 | test_canonicalize(L"\\\\?\\UNC\\server\\C$\\folder\\..\\..\\..\\..\\share\\", L"\\\\?\\UNC\\server\\share"); | |
258 | ||
259 | test_canonicalize(L"\\\\server\\share", L"\\\\server\\share"); | |
260 | test_canonicalize(L"\\\\server\\share\\", L"\\\\server\\share"); | |
261 | test_canonicalize(L"\\\\server\\share\\\\foo\\\\bar", L"\\\\server\\share\\foo\\bar"); | |
262 | test_canonicalize(L"\\\\server\\\\share\\\\foo\\\\bar", L"\\\\server\\share\\foo\\bar"); | |
263 | test_canonicalize(L"\\\\server\\share\\..\\foo", L"\\\\server\\foo"); | |
264 | test_canonicalize(L"\\\\server\\..\\..\\share\\.\\foo", L"\\\\server\\share\\foo"); | |
265 | #endif | |
266 | } | |
a64119e3 ET |
267 | |
268 | void test_path_win32__8dot3_name(void) | |
269 | { | |
270 | #ifdef GIT_WIN32 | |
271 | char *shortname; | |
272 | ||
07c989e9 | 273 | if (!cl_sandbox_supports_8dot3()) |
5f28ec84 ET |
274 | clar__skip(); |
275 | ||
07c989e9 ET |
276 | /* Some guaranteed short names */ |
277 | cl_assert_equal_s("PROGRA~1", (shortname = git_win32_path_8dot3_name("C:\\Program Files"))); | |
a64119e3 ET |
278 | git__free(shortname); |
279 | ||
280 | cl_assert_equal_s("WINDOWS", (shortname = git_win32_path_8dot3_name("C:\\WINDOWS"))); | |
281 | git__free(shortname); | |
282 | ||
283 | /* Create some predictible short names */ | |
284 | cl_must_pass(p_mkdir(".foo", 0777)); | |
5f28ec84 | 285 | cl_assert_equal_s("FOO~1", (shortname = git_win32_path_8dot3_name(".foo"))); |
a64119e3 ET |
286 | git__free(shortname); |
287 | ||
288 | cl_git_write2file("bar~1", "foobar\n", 7, O_RDWR|O_CREAT, 0666); | |
289 | cl_must_pass(p_mkdir(".bar", 0777)); | |
5f28ec84 | 290 | cl_assert_equal_s("BAR~2", (shortname = git_win32_path_8dot3_name(".bar"))); |
a64119e3 ET |
291 | git__free(shortname); |
292 | #endif | |
293 | } |