2 #include "clar_libgit2.h"
6 #include "win32/path_w32.h"
9 void test_utf8_to_utf16(const char *utf8_in
, const wchar_t *utf16_expected
)
12 git_win32_path path_utf16
;
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
);
20 GIT_UNUSED(utf16_expected
);
24 void test_utf8_to_utf16_relative(const char* utf8_in
, const wchar_t* utf16_expected
)
27 git_win32_path path_utf16
;
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
);
35 GIT_UNUSED(utf16_expected
);
39 void test_path_win32__utf8_to_utf16(void)
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:\\");
49 void test_path_win32__removes_trailing_slash(void)
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");
60 void test_path_win32__squashes_multiple_slashes(void)
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");
68 void test_path_win32__unc(void)
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");
76 void test_path_win32__honors_max_path(void)
79 git_win32_path path_utf16
;
81 test_utf8_to_utf16("C:\\This path is 261 characters which is fine for our path handling functions which cope with paths longer than MAX_PATH\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghijk",
82 L
"\\\\?\\C:\\This path is 261 characters which is fine for our path handling functions which cope with paths longer than MAX_PATH\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghijk");
84 cl_check_fail(git_win32_path_from_utf8(path_utf16
, "C:\\This path is 4097 chars and exceeds our maximum path length on Windows which is limited to 4096 characters\\alas\\0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij0123456789abcdefghij01"));
89 void test_path_win32__dot_and_dotdot(void)
92 test_utf8_to_utf16("C:\\Foo\\..\\Foobar", L
"\\\\?\\C:\\Foobar");
93 test_utf8_to_utf16("C:\\Foo\\Bar\\..\\Foobar", L
"\\\\?\\C:\\Foo\\Foobar");
94 test_utf8_to_utf16("C:\\Foo\\Bar\\..\\Foobar\\..", L
"\\\\?\\C:\\Foo");
95 test_utf8_to_utf16("C:\\Foobar\\..", L
"\\\\?\\C:\\");
96 test_utf8_to_utf16("C:/Foo/Bar/../Foobar", L
"\\\\?\\C:\\Foo\\Foobar");
97 test_utf8_to_utf16("C:/Foo/Bar/../Foobar/../Asdf/", L
"\\\\?\\C:\\Foo\\Asdf");
98 test_utf8_to_utf16("C:/Foo/Bar/../Foobar/..", L
"\\\\?\\C:\\Foo");
99 test_utf8_to_utf16("C:/Foo/..", L
"\\\\?\\C:\\");
101 test_utf8_to_utf16("C:\\Foo\\Bar\\.\\Foobar", L
"\\\\?\\C:\\Foo\\Bar\\Foobar");
102 test_utf8_to_utf16("C:\\.\\Foo\\.\\Bar\\.\\Foobar\\.\\", L
"\\\\?\\C:\\Foo\\Bar\\Foobar");
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:\\Bar");
106 test_utf8_to_utf16("C:\\Foo\\..\\..\\Bar", L
"\\\\?\\C:\\Bar");
110 void test_path_win32__absolute_from_no_drive_letter(void)
113 test_utf8_to_utf16("\\Foo", L
"\\\\?\\C:\\Foo");
114 test_utf8_to_utf16("\\Foo\\Bar", L
"\\\\?\\C:\\Foo\\Bar");
115 test_utf8_to_utf16("/Foo/Bar", L
"\\\\?\\C:\\Foo\\Bar");
119 void test_path_win32__absolute_from_relative(void)
122 char cwd_backup
[MAX_PATH
];
124 cl_must_pass(p_getcwd(cwd_backup
, MAX_PATH
));
125 cl_must_pass(p_chdir("C:/"));
127 test_utf8_to_utf16("Foo", L
"\\\\?\\C:\\Foo");
128 test_utf8_to_utf16("..\\..\\Foo", L
"\\\\?\\C:\\Foo");
129 test_utf8_to_utf16("Foo\\..", L
"\\\\?\\C:\\");
130 test_utf8_to_utf16("Foo\\..\\..", L
"\\\\?\\C:\\");
131 test_utf8_to_utf16("", L
"\\\\?\\C:\\");
133 cl_must_pass(p_chdir("C:/Windows"));
135 test_utf8_to_utf16("Foo", L
"\\\\?\\C:\\Windows\\Foo");
136 test_utf8_to_utf16("Foo\\Bar", L
"\\\\?\\C:\\Windows\\Foo\\Bar");
137 test_utf8_to_utf16("..\\Foo", L
"\\\\?\\C:\\Foo");
138 test_utf8_to_utf16("Foo\\..\\Bar", L
"\\\\?\\C:\\Windows\\Bar");
139 test_utf8_to_utf16("", L
"\\\\?\\C:\\Windows");
141 cl_must_pass(p_chdir(cwd_backup
));
145 void test_path_win32__keeps_relative(void)
148 /* Relative paths stay relative */
149 test_utf8_to_utf16_relative("Foo", L
"Foo");
150 test_utf8_to_utf16_relative("..\\..\\Foo", L
"..\\..\\Foo");
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\\Bar", L
"Foo\\Bar");
154 test_utf8_to_utf16_relative("Foo\\..\\Bar", L
"Foo\\..\\Bar");
155 test_utf8_to_utf16_relative("../../Foo", L
"..\\..\\Foo");
156 test_utf8_to_utf16_relative("Foo/..", L
"Foo\\..");
157 test_utf8_to_utf16_relative("Foo/../..", L
"Foo\\..\\..");
158 test_utf8_to_utf16_relative("Foo/Bar", L
"Foo\\Bar");
159 test_utf8_to_utf16_relative("Foo/../Bar", L
"Foo\\..\\Bar");
160 test_utf8_to_utf16_relative("Foo/../Bar/", L
"Foo\\..\\Bar\\");
161 test_utf8_to_utf16_relative("", L
"");
163 /* Absolute paths are canonicalized */
164 test_utf8_to_utf16_relative("\\Foo", L
"\\\\?\\C:\\Foo");
165 test_utf8_to_utf16_relative("/Foo/Bar/", L
"\\\\?\\C:\\Foo\\Bar");
166 test_utf8_to_utf16_relative("\\\\server\\c$\\unc\\path", L
"\\\\?\\UNC\\server\\c$\\unc\\path");
171 static void test_canonicalize(const wchar_t *in
, const wchar_t *expected
)
173 git_win32_path canonical
;
175 cl_assert(wcslen(in
) < MAX_PATH
);
176 wcscpy(canonical
, in
);
178 cl_must_pass(git_win32_path_canonicalize(canonical
));
179 cl_assert_equal_wcs(expected
, canonical
);
183 static void test_remove_namespace(const wchar_t *in
, const wchar_t *expected
)
186 git_win32_path canonical
;
188 cl_assert(wcslen(in
) < MAX_PATH
);
189 wcscpy(canonical
, in
);
191 git_win32_path_remove_namespace(canonical
, wcslen(in
));
192 cl_assert_equal_wcs(expected
, canonical
);
195 GIT_UNUSED(expected
);
199 void test_path_win32__remove_namespace(void)
201 test_remove_namespace(L
"\\\\?\\C:\\Temp\\Foo", L
"C:\\Temp\\Foo");
202 test_remove_namespace(L
"\\\\?\\C:\\", L
"C:\\");
203 test_remove_namespace(L
"\\\\?\\", L
"");
205 test_remove_namespace(L
"\\??\\C:\\Temp\\Foo", L
"C:\\Temp\\Foo");
206 test_remove_namespace(L
"\\??\\C:\\", L
"C:\\");
207 test_remove_namespace(L
"\\??\\", L
"");
209 test_remove_namespace(L
"\\\\?\\UNC\\server\\C$\\folder", L
"\\\\server\\C$\\folder");
210 test_remove_namespace(L
"\\\\?\\UNC\\server\\C$\\folder", L
"\\\\server\\C$\\folder");
211 test_remove_namespace(L
"\\\\?\\UNC\\server\\C$", L
"\\\\server\\C$");
212 test_remove_namespace(L
"\\\\?\\UNC\\server\\", L
"\\\\server");
213 test_remove_namespace(L
"\\\\?\\UNC\\server", L
"\\\\server");
215 test_remove_namespace(L
"\\??\\UNC\\server\\C$\\folder", L
"\\\\server\\C$\\folder");
216 test_remove_namespace(L
"\\??\\UNC\\server\\C$\\folder", L
"\\\\server\\C$\\folder");
217 test_remove_namespace(L
"\\??\\UNC\\server\\C$", L
"\\\\server\\C$");
218 test_remove_namespace(L
"\\??\\UNC\\server\\", L
"\\\\server");
219 test_remove_namespace(L
"\\??\\UNC\\server", L
"\\\\server");
221 test_remove_namespace(L
"\\\\server\\C$\\folder", L
"\\\\server\\C$\\folder");
222 test_remove_namespace(L
"\\\\server\\C$", L
"\\\\server\\C$");
223 test_remove_namespace(L
"\\\\server\\", L
"\\\\server");
224 test_remove_namespace(L
"\\\\server", L
"\\\\server");
226 test_remove_namespace(L
"C:\\Foo\\Bar", L
"C:\\Foo\\Bar");
227 test_remove_namespace(L
"C:\\", L
"C:\\");
228 test_remove_namespace(L
"", L
"");
232 void test_path_win32__canonicalize(void)
235 test_canonicalize(L
"C:\\Foo\\Bar", L
"C:\\Foo\\Bar");
236 test_canonicalize(L
"C:\\Foo\\", L
"C:\\Foo");
237 test_canonicalize(L
"C:\\Foo\\\\", L
"C:\\Foo");
238 test_canonicalize(L
"C:\\Foo\\..\\Bar", L
"C:\\Bar");
239 test_canonicalize(L
"C:\\Foo\\..\\..\\Bar", L
"C:\\Bar");
240 test_canonicalize(L
"C:\\Foo\\..\\..\\..\\..\\", L
"C:\\");
241 test_canonicalize(L
"C:/Foo/Bar", L
"C:\\Foo\\Bar");
242 test_canonicalize(L
"C:/", L
"C:\\");
244 test_canonicalize(L
"\\\\?\\C:\\Foo\\Bar", L
"\\\\?\\C:\\Foo\\Bar");
245 test_canonicalize(L
"\\\\?\\C:\\Foo\\Bar\\", L
"\\\\?\\C:\\Foo\\Bar");
246 test_canonicalize(L
"\\\\?\\C:\\\\Foo\\.\\Bar\\\\..\\", L
"\\\\?\\C:\\Foo");
247 test_canonicalize(L
"\\\\?\\C:\\\\", L
"\\\\?\\C:\\");
248 test_canonicalize(L
"//?/C:/", L
"\\\\?\\C:\\");
249 test_canonicalize(L
"//?/C:/../../Foo/", L
"\\\\?\\C:\\Foo");
250 test_canonicalize(L
"//?/C:/Foo/../../", L
"\\\\?\\C:\\");
252 test_canonicalize(L
"\\\\?\\UNC\\server\\C$\\folder", L
"\\\\?\\UNC\\server\\C$\\folder");
253 test_canonicalize(L
"\\\\?\\UNC\\server\\C$\\folder\\", L
"\\\\?\\UNC\\server\\C$\\folder");
254 test_canonicalize(L
"\\\\?\\UNC\\server\\C$\\folder\\", L
"\\\\?\\UNC\\server\\C$\\folder");
255 test_canonicalize(L
"\\\\?\\UNC\\server\\C$\\folder\\..\\..\\..\\..\\share\\", L
"\\\\?\\UNC\\server\\share");
257 test_canonicalize(L
"\\\\server\\share", L
"\\\\server\\share");
258 test_canonicalize(L
"\\\\server\\share\\", L
"\\\\server\\share");
259 test_canonicalize(L
"\\\\server\\share\\\\foo\\\\bar", L
"\\\\server\\share\\foo\\bar");
260 test_canonicalize(L
"\\\\server\\\\share\\\\foo\\\\bar", L
"\\\\server\\share\\foo\\bar");
261 test_canonicalize(L
"\\\\server\\share\\..\\foo", L
"\\\\server\\foo");
262 test_canonicalize(L
"\\\\server\\..\\..\\share\\.\\foo", L
"\\\\server\\share\\foo");
266 void test_path_win32__8dot3_name(void)
271 if (!cl_sandbox_supports_8dot3())
274 /* Some guaranteed short names */
275 cl_assert_equal_s("PROGRA~1", (shortname
= git_win32_path_8dot3_name("C:\\Program Files")));
276 git__free(shortname
);
278 cl_assert_equal_s("WINDOWS", (shortname
= git_win32_path_8dot3_name("C:\\WINDOWS")));
279 git__free(shortname
);
281 /* Create some predictible short names */
282 cl_must_pass(p_mkdir(".foo", 0777));
283 cl_assert_equal_s("FOO~1", (shortname
= git_win32_path_8dot3_name(".foo")));
284 git__free(shortname
);
286 cl_git_write2file("bar~1", "foobar\n", 7, O_RDWR
|O_CREAT
, 0666);
287 cl_must_pass(p_mkdir(".bar", 0777));
288 cl_assert_equal_s("BAR~2", (shortname
= git_win32_path_8dot3_name(".bar")));
289 git__free(shortname
);