]> git.proxmox.com Git - libgit2.git/blame - tests/core/path.c
New upstream version 1.4.3+dfsg.1
[libgit2.git] / tests / core / path.c
CommitLineData
3fd1520c 1#include "clar_libgit2.h"
22a2d3d5 2#include "futils.h"
e579e0f7
MB
3#include "fs_path.h"
4
5static char *path_save;
6
7void test_core_path__initialize(void)
8{
9 path_save = cl_getenv("PATH");
10}
11
12void test_core_path__cleanup(void)
13{
14 cl_setenv("PATH", path_save);
15 git__free(path_save);
16 path_save = NULL;
17}
f1558d9b
VM
18
19static void
20check_dirname(const char *A, const char *B)
21{
e579e0f7 22 git_str dir = GIT_STR_INIT;
97769280 23 char *dir2;
f1558d9b 24
e579e0f7 25 cl_assert(git_fs_path_dirname_r(&dir, A) >= 0);
1a6e8f8a 26 cl_assert_equal_s(B, dir.ptr);
e579e0f7 27 git_str_dispose(&dir);
f1558d9b 28
e579e0f7 29 cl_assert((dir2 = git_fs_path_dirname(A)) != NULL);
1a6e8f8a 30 cl_assert_equal_s(B, dir2);
3286c408 31 git__free(dir2);
f1558d9b
VM
32}
33
34static void
35check_basename(const char *A, const char *B)
36{
e579e0f7 37 git_str base = GIT_STR_INIT;
97769280 38 char *base2;
f1558d9b 39
e579e0f7 40 cl_assert(git_fs_path_basename_r(&base, A) >= 0);
1a6e8f8a 41 cl_assert_equal_s(B, base.ptr);
e579e0f7 42 git_str_dispose(&base);
f1558d9b 43
e579e0f7 44 cl_assert((base2 = git_fs_path_basename(A)) != NULL);
1a6e8f8a 45 cl_assert_equal_s(B, base2);
3286c408 46 git__free(base2);
f1558d9b
VM
47}
48
f1558d9b
VM
49static void
50check_joinpath(const char *path_a, const char *path_b, const char *expected_path)
51{
e579e0f7 52 git_str joined_path = GIT_STR_INIT;
f1558d9b 53
e579e0f7 54 cl_git_pass(git_str_joinpath(&joined_path, path_a, path_b));
1a6e8f8a 55 cl_assert_equal_s(expected_path, joined_path.ptr);
97769280 56
e579e0f7 57 git_str_dispose(&joined_path);
f1558d9b
VM
58}
59
60static void
61check_joinpath_n(
62 const char *path_a,
63 const char *path_b,
64 const char *path_c,
65 const char *path_d,
66 const char *expected_path)
67{
e579e0f7 68 git_str joined_path = GIT_STR_INIT;
97769280 69
e579e0f7 70 cl_git_pass(git_str_join_n(&joined_path, '/', 4,
97769280 71 path_a, path_b, path_c, path_d));
1a6e8f8a 72 cl_assert_equal_s(expected_path, joined_path.ptr);
f1558d9b 73
e579e0f7 74 git_str_dispose(&joined_path);
f1558d9b
VM
75}
76
e579e0f7
MB
77static void check_setenv(const char* name, const char* value)
78{
79 char* check;
80
81 cl_git_pass(cl_setenv(name, value));
82 check = cl_getenv(name);
83
84 if (value)
85 cl_assert_equal_s(value, check);
86 else
87 cl_assert(check == NULL);
88
89 git__free(check);
90}
f1558d9b
VM
91
92/* get the dirname of a path */
2017a15d 93void test_core_path__00_dirname(void)
f1558d9b 94{
f1558d9b
VM
95 check_dirname(NULL, ".");
96 check_dirname("", ".");
97 check_dirname("a", ".");
98 check_dirname("/", "/");
99 check_dirname("/usr", "/");
100 check_dirname("/usr/", "/");
101 check_dirname("/usr/lib", "/usr");
102 check_dirname("/usr/lib/", "/usr");
103 check_dirname("/usr/lib//", "/usr");
104 check_dirname("usr/lib", "usr");
105 check_dirname("usr/lib/", "usr");
106 check_dirname("usr/lib//", "usr");
107 check_dirname(".git/", ".");
97769280
RB
108
109 check_dirname(REP16("/abc"), REP15("/abc"));
34b6f05f 110
111#ifdef GIT_WIN32
5d59520c 112 check_dirname("C:/", "C:/");
9e8d75c7 113 check_dirname("C:", "C:/");
34b6f05f 114 check_dirname("C:/path/", "C:/");
115 check_dirname("C:/path", "C:/");
5d59520c 116 check_dirname("//computername/", "//computername/");
9e8d75c7 117 check_dirname("//computername", "//computername/");
50a762a5 118 check_dirname("//computername/path/", "//computername/");
119 check_dirname("//computername/path", "//computername/");
120 check_dirname("//computername/sub/path/", "//computername/sub");
121 check_dirname("//computername/sub/path", "//computername/sub");
34b6f05f 122#endif
f1558d9b
VM
123}
124
125/* get the base name of a path */
2017a15d 126void test_core_path__01_basename(void)
f1558d9b
VM
127{
128 check_basename(NULL, ".");
129 check_basename("", ".");
130 check_basename("a", "a");
131 check_basename("/", "/");
132 check_basename("/usr", "usr");
133 check_basename("/usr/", "usr");
134 check_basename("/usr/lib", "lib");
135 check_basename("/usr/lib//", "lib");
136 check_basename("usr/lib", "lib");
97769280
RB
137
138 check_basename(REP16("/abc"), "abc");
139 check_basename(REP1024("/abc"), "abc");
f1558d9b
VM
140}
141
f1558d9b 142/* properly join path components */
2017a15d 143void test_core_path__05_joins(void)
f1558d9b
VM
144{
145 check_joinpath("", "", "");
146 check_joinpath("", "a", "a");
147 check_joinpath("", "/a", "/a");
148 check_joinpath("a", "", "a/");
149 check_joinpath("a", "/", "a/");
150 check_joinpath("a", "b", "a/b");
151 check_joinpath("/", "a", "/a");
152 check_joinpath("/", "", "/");
153 check_joinpath("/a", "/b", "/a/b");
154 check_joinpath("/a", "/b/", "/a/b/");
155 check_joinpath("/a/", "b/", "/a/b/");
156 check_joinpath("/a/", "/b/", "/a/b/");
97769280
RB
157
158 check_joinpath("/abcd", "/defg", "/abcd/defg");
159 check_joinpath("/abcd", "/defg/", "/abcd/defg/");
160 check_joinpath("/abcd/", "defg/", "/abcd/defg/");
161 check_joinpath("/abcd/", "/defg/", "/abcd/defg/");
162
163 check_joinpath("/abcdefgh", "/12345678", "/abcdefgh/12345678");
164 check_joinpath("/abcdefgh", "/12345678/", "/abcdefgh/12345678/");
165 check_joinpath("/abcdefgh/", "12345678/", "/abcdefgh/12345678/");
166
b5daae68
RB
167 check_joinpath(REP1024("aaaa"), "", REP1024("aaaa") "/");
168 check_joinpath(REP1024("aaaa/"), "", REP1024("aaaa/"));
169 check_joinpath(REP1024("/aaaa"), "", REP1024("/aaaa") "/");
170
97769280
RB
171 check_joinpath(REP1024("aaaa"), REP1024("bbbb"),
172 REP1024("aaaa") "/" REP1024("bbbb"));
173 check_joinpath(REP1024("/aaaa"), REP1024("/bbbb"),
174 REP1024("/aaaa") REP1024("/bbbb"));
f1558d9b
VM
175}
176
177/* properly join path components for more than one path */
2017a15d 178void test_core_path__06_long_joins(void)
f1558d9b
VM
179{
180 check_joinpath_n("", "", "", "", "");
181 check_joinpath_n("", "a", "", "", "a/");
182 check_joinpath_n("a", "", "", "", "a/");
183 check_joinpath_n("", "", "", "a", "a");
184 check_joinpath_n("a", "b", "", "/c/d/", "a/b/c/d/");
185 check_joinpath_n("a", "b", "", "/c/d", "a/b/c/d");
97769280
RB
186 check_joinpath_n("abcd", "efgh", "ijkl", "mnop", "abcd/efgh/ijkl/mnop");
187 check_joinpath_n("abcd/", "efgh/", "ijkl/", "mnop/", "abcd/efgh/ijkl/mnop/");
188 check_joinpath_n("/abcd/", "/efgh/", "/ijkl/", "/mnop/", "/abcd/efgh/ijkl/mnop/");
189
190 check_joinpath_n(REP1024("a"), REP1024("b"), REP1024("c"), REP1024("d"),
191 REP1024("a") "/" REP1024("b") "/"
192 REP1024("c") "/" REP1024("d"));
193 check_joinpath_n(REP1024("/a"), REP1024("/b"), REP1024("/c"), REP1024("/d"),
194 REP1024("/a") REP1024("/b")
195 REP1024("/c") REP1024("/d"));
196}
197
198
199static void
200check_path_to_dir(
201 const char* path,
202 const char* expected)
203{
e579e0f7 204 git_str tgt = GIT_STR_INIT;
97769280 205
e579e0f7
MB
206 git_str_sets(&tgt, path);
207 cl_git_pass(git_fs_path_to_dir(&tgt));
1a6e8f8a 208 cl_assert_equal_s(expected, tgt.ptr);
97769280 209
e579e0f7 210 git_str_dispose(&tgt);
97769280
RB
211}
212
213static void
214check_string_to_dir(
215 const char* path,
1a6e8f8a 216 size_t maxlen,
97769280
RB
217 const char* expected)
218{
1a6e8f8a 219 size_t len = strlen(path);
97769280 220 char *buf = git__malloc(len + 2);
1a6e8f8a
RB
221 cl_assert(buf);
222
97769280
RB
223 strncpy(buf, path, len + 2);
224
e579e0f7 225 git_fs_path_string_to_dir(buf, maxlen);
97769280 226
1a6e8f8a 227 cl_assert_equal_s(expected, buf);
97769280
RB
228
229 git__free(buf);
230}
231
232/* convert paths to dirs */
2017a15d 233void test_core_path__07_path_to_dir(void)
97769280
RB
234{
235 check_path_to_dir("", "");
236 check_path_to_dir(".", "./");
237 check_path_to_dir("./", "./");
238 check_path_to_dir("a/", "a/");
239 check_path_to_dir("ab", "ab/");
240 /* make sure we try just under and just over an expansion that will
241 * require a realloc
242 */
243 check_path_to_dir("abcdef", "abcdef/");
244 check_path_to_dir("abcdefg", "abcdefg/");
245 check_path_to_dir("abcdefgh", "abcdefgh/");
246 check_path_to_dir("abcdefghi", "abcdefghi/");
247 check_path_to_dir(REP1024("abcd") "/", REP1024("abcd") "/");
248 check_path_to_dir(REP1024("abcd"), REP1024("abcd") "/");
249
250 check_string_to_dir("", 1, "");
251 check_string_to_dir(".", 1, ".");
252 check_string_to_dir(".", 2, "./");
253 check_string_to_dir(".", 3, "./");
254 check_string_to_dir("abcd", 3, "abcd");
255 check_string_to_dir("abcd", 4, "abcd");
256 check_string_to_dir("abcd", 5, "abcd/");
257 check_string_to_dir("abcd", 6, "abcd/");
f1558d9b 258}
b5daae68
RB
259
260/* join path to itself */
2017a15d 261void test_core_path__08_self_join(void)
b5daae68 262{
e579e0f7 263 git_str path = GIT_STR_INIT;
13224ea4 264 size_t asize = 0;
b5daae68
RB
265
266 asize = path.asize;
e579e0f7 267 cl_git_pass(git_str_sets(&path, "/foo"));
1a6e8f8a 268 cl_assert_equal_s(path.ptr, "/foo");
b5daae68
RB
269 cl_assert(asize < path.asize);
270
271 asize = path.asize;
e579e0f7 272 cl_git_pass(git_str_joinpath(&path, path.ptr, "this is a new string"));
1a6e8f8a 273 cl_assert_equal_s(path.ptr, "/foo/this is a new string");
b5daae68
RB
274 cl_assert(asize < path.asize);
275
276 asize = path.asize;
e579e0f7 277 cl_git_pass(git_str_joinpath(&path, path.ptr, "/grow the buffer, grow the buffer, grow the buffer"));
1a6e8f8a 278 cl_assert_equal_s(path.ptr, "/foo/this is a new string/grow the buffer, grow the buffer, grow the buffer");
b5daae68
RB
279 cl_assert(asize < path.asize);
280
e579e0f7
MB
281 git_str_dispose(&path);
282 cl_git_pass(git_str_sets(&path, "/foo/bar"));
b5daae68 283
e579e0f7 284 cl_git_pass(git_str_joinpath(&path, path.ptr + 4, "baz"));
1a6e8f8a 285 cl_assert_equal_s(path.ptr, "/bar/baz");
b5daae68
RB
286
287 asize = path.asize;
e579e0f7 288 cl_git_pass(git_str_joinpath(&path, path.ptr + 4, "somethinglongenoughtorealloc"));
1a6e8f8a 289 cl_assert_equal_s(path.ptr, "/baz/somethinglongenoughtorealloc");
b5daae68 290 cl_assert(asize < path.asize);
c25aa7cd 291
e579e0f7 292 git_str_dispose(&path);
b5daae68 293}
459e2dcd 294
295static void check_percent_decoding(const char *expected_result, const char *input)
296{
e579e0f7 297 git_str buf = GIT_STR_INIT;
459e2dcd 298
299 cl_git_pass(git__percent_decode(&buf, input));
e579e0f7 300 cl_assert_equal_s(expected_result, git_str_cstr(&buf));
459e2dcd 301
e579e0f7 302 git_str_dispose(&buf);
459e2dcd 303}
304
2017a15d 305void test_core_path__09_percent_decode(void)
459e2dcd 306{
307 check_percent_decoding("abcd", "abcd");
308 check_percent_decoding("a2%", "a2%");
309 check_percent_decoding("a2%3", "a2%3");
310 check_percent_decoding("a2%%3", "a2%%3");
311 check_percent_decoding("a2%3z", "a2%3z");
312 check_percent_decoding("a,", "a%2c");
313 check_percent_decoding("a21", "a2%31");
314 check_percent_decoding("a2%1", "a2%%31");
315 check_percent_decoding("a bc ", "a%20bc%20");
316 check_percent_decoding("Vicent Mart" "\355", "Vicent%20Mart%ED");
317}
2017a15d 318
319static void check_fromurl(const char *expected_result, const char *input, int should_fail)
320{
e579e0f7 321 git_str buf = GIT_STR_INIT;
2017a15d 322
323 assert(should_fail || expected_result);
324
325 if (!should_fail) {
e579e0f7
MB
326 cl_git_pass(git_fs_path_fromurl(&buf, input));
327 cl_assert_equal_s(expected_result, git_str_cstr(&buf));
2017a15d 328 } else
e579e0f7 329 cl_git_fail(git_fs_path_fromurl(&buf, input));
2017a15d 330
e579e0f7 331 git_str_dispose(&buf);
2017a15d 332}
333
8c29dca6 334#ifdef GIT_WIN32
2017a15d 335#define ABS_PATH_MARKER ""
336#else
337#define ABS_PATH_MARKER "/"
338#endif
339
340void test_core_path__10_fromurl(void)
341{
342 /* Failing cases */
343 check_fromurl(NULL, "a", 1);
344 check_fromurl(NULL, "http:///c:/Temp%20folder/note.txt", 1);
345 check_fromurl(NULL, "file://c:/Temp%20folder/note.txt", 1);
346 check_fromurl(NULL, "file:////c:/Temp%20folder/note.txt", 1);
347 check_fromurl(NULL, "file:///", 1);
348 check_fromurl(NULL, "file:////", 1);
349 check_fromurl(NULL, "file://servername/c:/Temp%20folder/note.txt", 1);
350
351 /* Passing cases */
352 check_fromurl(ABS_PATH_MARKER "c:/Temp folder/note.txt", "file:///c:/Temp%20folder/note.txt", 0);
353 check_fromurl(ABS_PATH_MARKER "c:/Temp folder/note.txt", "file://localhost/c:/Temp%20folder/note.txt", 0);
354 check_fromurl(ABS_PATH_MARKER "c:/Temp+folder/note.txt", "file:///c:/Temp+folder/note.txt", 0);
355 check_fromurl(ABS_PATH_MARKER "a", "file:///a", 0);
356}
df743c7d 357
0cfcff5d
RB
358typedef struct {
359 int expect_idx;
dab89f9b 360 int cancel_after;
0cfcff5d
RB
361 char **expect;
362} check_walkup_info;
363
25e0b157
RB
364#define CANCEL_VALUE 1234
365
bbb988a5 366static int check_one_walkup_step(void *ref, const char *path)
0cfcff5d
RB
367{
368 check_walkup_info *info = (check_walkup_info *)ref;
dab89f9b
RB
369
370 if (!info->cancel_after) {
371 cl_assert_equal_s(info->expect[info->expect_idx], "[CANCEL]");
25e0b157 372 return CANCEL_VALUE;
dab89f9b
RB
373 }
374 info->cancel_after--;
375
0cfcff5d 376 cl_assert(info->expect[info->expect_idx] != NULL);
bbb988a5 377 cl_assert_equal_s(info->expect[info->expect_idx], path);
0cfcff5d 378 info->expect_idx++;
dab89f9b 379
0d0fa7c3 380 return 0;
0cfcff5d
RB
381}
382
df743c7d
RB
383void test_core_path__11_walkup(void)
384{
e579e0f7 385 git_str p = GIT_STR_INIT;
bbb988a5 386
df743c7d 387 char *expect[] = {
bbb988a5
T
388 /* 1 */ "/a/b/c/d/e/", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
389 /* 2 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
390 /* 3 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
391 /* 4 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", "/a/", "/", NULL,
392 /* 5 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", NULL,
393 /* 6 */ "/a/b/c/d/e", "/a/b/c/d/", "/a/b/c/", "/a/b/", NULL,
394 /* 7 */ "this_is_a_path", "", NULL,
395 /* 8 */ "this_is_a_path/", "", NULL,
396 /* 9 */ "///a///b///c///d///e///", "///a///b///c///d///", "///a///b///c///", "///a///b///", "///a///", "///", NULL,
397 /* 10 */ "a/b/c/", "a/b/", "a/", "", NULL,
398 /* 11 */ "a/b/c", "a/b/", "a/", "", NULL,
399 /* 12 */ "a/b/c/", "a/b/", "a/", NULL,
400 /* 13 */ "", NULL,
401 /* 14 */ "/", NULL,
402 /* 15 */ NULL
403 };
404
405 char *root[] = {
406 /* 1 */ NULL,
407 /* 2 */ NULL,
408 /* 3 */ "/",
409 /* 4 */ "",
410 /* 5 */ "/a/b",
411 /* 6 */ "/a/b/",
412 /* 7 */ NULL,
413 /* 8 */ NULL,
414 /* 9 */ NULL,
415 /* 10 */ NULL,
416 /* 11 */ NULL,
417 /* 12 */ "a/",
418 /* 13 */ NULL,
419 /* 14 */ NULL,
df743c7d 420 };
bbb988a5 421
df743c7d 422 int i, j;
0cfcff5d
RB
423 check_walkup_info info;
424
425 info.expect = expect;
dab89f9b 426 info.cancel_after = -1;
df743c7d
RB
427
428 for (i = 0, j = 0; expect[i] != NULL; i++, j++) {
df743c7d 429
e579e0f7 430 git_str_sets(&p, expect[i]);
df743c7d 431
0cfcff5d
RB
432 info.expect_idx = i;
433 cl_git_pass(
e579e0f7 434 git_fs_path_walk_up(&p, root[j], check_one_walkup_step, &info)
0cfcff5d 435 );
df743c7d 436
1a6e8f8a 437 cl_assert_equal_s(p.ptr, expect[i]);
bbb988a5
T
438 cl_assert(expect[info.expect_idx] == NULL);
439 i = info.expect_idx;
dab89f9b
RB
440 }
441
e579e0f7 442 git_str_dispose(&p);
dab89f9b
RB
443}
444
445void test_core_path__11a_walkup_cancel(void)
446{
e579e0f7 447 git_str p = GIT_STR_INIT;
dab89f9b
RB
448 int cancel[] = { 3, 2, 1, 0 };
449 char *expect[] = {
450 "/a/b/c/d/e/", "/a/b/c/d/", "/a/b/c/", "[CANCEL]", NULL,
451 "/a/b/c/d/e", "/a/b/c/d/", "[CANCEL]", NULL,
452 "/a/b/c/d/e", "[CANCEL]", NULL,
453 "[CANCEL]", NULL,
454 NULL
455 };
456 char *root[] = { NULL, NULL, "/", "", NULL };
457 int i, j;
458 check_walkup_info info;
459
460 info.expect = expect;
461
462 for (i = 0, j = 0; expect[i] != NULL; i++, j++) {
463
e579e0f7 464 git_str_sets(&p, expect[i]);
dab89f9b
RB
465
466 info.cancel_after = cancel[j];
467 info.expect_idx = i;
468
469 cl_assert_equal_i(
25e0b157 470 CANCEL_VALUE,
e579e0f7 471 git_fs_path_walk_up(&p, root[j], check_one_walkup_step, &info)
dab89f9b
RB
472 );
473
df743c7d
RB
474 /* skip to next run of expectations */
475 while (expect[i] != NULL) i++;
476 }
477
e579e0f7 478 git_str_dispose(&p);
df743c7d 479}
7b93079b 480
481void test_core_path__12_offset_to_path_root(void)
482{
e579e0f7
MB
483 cl_assert(git_fs_path_root("non/rooted/path") == -1);
484 cl_assert(git_fs_path_root("/rooted/path") == 0);
7b93079b 485
486#ifdef GIT_WIN32
487 /* Windows specific tests */
e579e0f7
MB
488 cl_assert(git_fs_path_root("C:non/rooted/path") == -1);
489 cl_assert(git_fs_path_root("C:/rooted/path") == 2);
490 cl_assert(git_fs_path_root("//computername/sharefolder/resource") == 14);
491 cl_assert(git_fs_path_root("//computername/sharefolder") == 14);
492 cl_assert(git_fs_path_root("//computername") == -1);
7b93079b 493#endif
494}
9abb5bca 495
496#define NON_EXISTING_FILEPATH "i_hope_i_do_not_exist"
497
498void test_core_path__13_cannot_prettify_a_non_existing_file(void)
499{
e579e0f7 500 git_str p = GIT_STR_INIT;
9abb5bca 501
e579e0f7
MB
502 cl_assert_equal_b(git_fs_path_exists(NON_EXISTING_FILEPATH), false);
503 cl_assert_equal_i(GIT_ENOTFOUND, git_fs_path_prettify(&p, NON_EXISTING_FILEPATH, NULL));
504 cl_assert_equal_i(GIT_ENOTFOUND, git_fs_path_prettify(&p, NON_EXISTING_FILEPATH "/so-do-i", NULL));
9abb5bca 505
e579e0f7 506 git_str_dispose(&p);
9abb5bca 507}
b0fe1129
RB
508
509void test_core_path__14_apply_relative(void)
510{
e579e0f7 511 git_str p = GIT_STR_INIT;
b0fe1129 512
e579e0f7 513 cl_git_pass(git_str_sets(&p, "/this/is/a/base"));
b0fe1129 514
e579e0f7 515 cl_git_pass(git_fs_path_apply_relative(&p, "../test"));
b0fe1129
RB
516 cl_assert_equal_s("/this/is/a/test", p.ptr);
517
e579e0f7 518 cl_git_pass(git_fs_path_apply_relative(&p, "../../the/./end"));
b0fe1129
RB
519 cl_assert_equal_s("/this/is/the/end", p.ptr);
520
e579e0f7 521 cl_git_pass(git_fs_path_apply_relative(&p, "./of/this/../the/string"));
b0fe1129
RB
522 cl_assert_equal_s("/this/is/the/end/of/the/string", p.ptr);
523
e579e0f7 524 cl_git_pass(git_fs_path_apply_relative(&p, "../../../../../.."));
b0fe1129
RB
525 cl_assert_equal_s("/this/", p.ptr);
526
e579e0f7 527 cl_git_pass(git_fs_path_apply_relative(&p, "../"));
b0fe1129
RB
528 cl_assert_equal_s("/", p.ptr);
529
e579e0f7 530 cl_git_fail(git_fs_path_apply_relative(&p, "../../.."));
b0fe1129
RB
531
532
e579e0f7 533 cl_git_pass(git_str_sets(&p, "d:/another/test"));
b0fe1129 534
e579e0f7 535 cl_git_pass(git_fs_path_apply_relative(&p, "../.."));
b0fe1129
RB
536 cl_assert_equal_s("d:/", p.ptr);
537
e579e0f7 538 cl_git_pass(git_fs_path_apply_relative(&p, "from/here/to/../and/./back/."));
b0fe1129
RB
539 cl_assert_equal_s("d:/from/here/and/back/", p.ptr);
540
541
e579e0f7 542 cl_git_pass(git_str_sets(&p, "https://my.url.com/test.git"));
b0fe1129 543
e579e0f7 544 cl_git_pass(git_fs_path_apply_relative(&p, "../another.git"));
b0fe1129
RB
545 cl_assert_equal_s("https://my.url.com/another.git", p.ptr);
546
e579e0f7 547 cl_git_pass(git_fs_path_apply_relative(&p, "../full/path/url.patch"));
b0fe1129
RB
548 cl_assert_equal_s("https://my.url.com/full/path/url.patch", p.ptr);
549
e579e0f7 550 cl_git_pass(git_fs_path_apply_relative(&p, ".."));
b0fe1129
RB
551 cl_assert_equal_s("https://my.url.com/full/path/", p.ptr);
552
e579e0f7 553 cl_git_pass(git_fs_path_apply_relative(&p, "../../../"));
b0fe1129
RB
554 cl_assert_equal_s("https://", p.ptr);
555
6d9a6c5c 556
e579e0f7 557 cl_git_pass(git_str_sets(&p, "../../this/is/relative"));
6d9a6c5c 558
e579e0f7 559 cl_git_pass(git_fs_path_apply_relative(&p, "../../preserves/the/prefix"));
6d9a6c5c
NV
560 cl_assert_equal_s("../../this/preserves/the/prefix", p.ptr);
561
e579e0f7 562 cl_git_pass(git_fs_path_apply_relative(&p, "../../../../that"));
6d9a6c5c
NV
563 cl_assert_equal_s("../../that", p.ptr);
564
e579e0f7 565 cl_git_pass(git_fs_path_apply_relative(&p, "../there"));
6d9a6c5c 566 cl_assert_equal_s("../../there", p.ptr);
e579e0f7 567 git_str_dispose(&p);
b0fe1129 568}
6d9a6c5c 569
0d1af399 570static void assert_resolve_relative(
e579e0f7 571 git_str *buf, const char *expected, const char *path)
6d9a6c5c 572{
e579e0f7
MB
573 cl_git_pass(git_str_sets(buf, path));
574 cl_git_pass(git_fs_path_resolve_relative(buf, 0));
6d9a6c5c
NV
575 cl_assert_equal_s(expected, buf->ptr);
576}
577
578void test_core_path__15_resolve_relative(void)
579{
e579e0f7 580 git_str buf = GIT_STR_INIT;
6d9a6c5c
NV
581
582 assert_resolve_relative(&buf, "", "");
583 assert_resolve_relative(&buf, "", ".");
584 assert_resolve_relative(&buf, "", "./");
585 assert_resolve_relative(&buf, "..", "..");
586 assert_resolve_relative(&buf, "../", "../");
587 assert_resolve_relative(&buf, "..", "./..");
588 assert_resolve_relative(&buf, "../", "./../");
589 assert_resolve_relative(&buf, "../", "../.");
590 assert_resolve_relative(&buf, "../", ".././");
591 assert_resolve_relative(&buf, "../..", "../..");
592 assert_resolve_relative(&buf, "../../", "../../");
593
594 assert_resolve_relative(&buf, "/", "/");
595 assert_resolve_relative(&buf, "/", "/.");
596
597 assert_resolve_relative(&buf, "", "a/..");
598 assert_resolve_relative(&buf, "", "a/../");
599 assert_resolve_relative(&buf, "", "a/../.");
600
601 assert_resolve_relative(&buf, "/a", "/a");
602 assert_resolve_relative(&buf, "/a/", "/a/.");
603 assert_resolve_relative(&buf, "/", "/a/../");
604 assert_resolve_relative(&buf, "/", "/a/../.");
605 assert_resolve_relative(&buf, "/", "/a/.././");
606
607 assert_resolve_relative(&buf, "a", "a");
608 assert_resolve_relative(&buf, "a/", "a/");
609 assert_resolve_relative(&buf, "a/", "a/.");
610 assert_resolve_relative(&buf, "a/", "a/./");
611
612 assert_resolve_relative(&buf, "a/b", "a//b");
613 assert_resolve_relative(&buf, "a/b/c", "a/b/c");
614 assert_resolve_relative(&buf, "b/c", "./b/c");
615 assert_resolve_relative(&buf, "a/c", "a/./c");
616 assert_resolve_relative(&buf, "a/b/", "a/b/.");
617
618 assert_resolve_relative(&buf, "/a/b/c", "///a/b/c");
6d9a6c5c
NV
619 assert_resolve_relative(&buf, "/", "////");
620 assert_resolve_relative(&buf, "/a", "///a");
621 assert_resolve_relative(&buf, "/", "///.");
622 assert_resolve_relative(&buf, "/", "///a/..");
623
624 assert_resolve_relative(&buf, "../../path", "../../test//../././path");
625 assert_resolve_relative(&buf, "../d", "a/b/../../../c/../d");
626
e579e0f7
MB
627 cl_git_pass(git_str_sets(&buf, "/.."));
628 cl_git_fail(git_fs_path_resolve_relative(&buf, 0));
6d9a6c5c 629
e579e0f7
MB
630 cl_git_pass(git_str_sets(&buf, "/./.."));
631 cl_git_fail(git_fs_path_resolve_relative(&buf, 0));
6d9a6c5c 632
e579e0f7
MB
633 cl_git_pass(git_str_sets(&buf, "/.//.."));
634 cl_git_fail(git_fs_path_resolve_relative(&buf, 0));
6d9a6c5c 635
e579e0f7
MB
636 cl_git_pass(git_str_sets(&buf, "/../."));
637 cl_git_fail(git_fs_path_resolve_relative(&buf, 0));
6d9a6c5c 638
e579e0f7
MB
639 cl_git_pass(git_str_sets(&buf, "/../.././../a"));
640 cl_git_fail(git_fs_path_resolve_relative(&buf, 0));
6d9a6c5c 641
e579e0f7
MB
642 cl_git_pass(git_str_sets(&buf, "////.."));
643 cl_git_fail(git_fs_path_resolve_relative(&buf, 0));
6d9a6c5c 644
cae52938
RB
645 /* things that start with Windows network paths */
646#ifdef GIT_WIN32
647 assert_resolve_relative(&buf, "//a/b/c", "//a/b/c");
648 assert_resolve_relative(&buf, "//a/", "//a/b/..");
649 assert_resolve_relative(&buf, "//a/b/c", "//a/Q/../b/x/y/../../c");
650
e579e0f7
MB
651 cl_git_pass(git_str_sets(&buf, "//a/b/../.."));
652 cl_git_fail(git_fs_path_resolve_relative(&buf, 0));
cae52938
RB
653#else
654 assert_resolve_relative(&buf, "/a/b/c", "//a/b/c");
655 assert_resolve_relative(&buf, "/a/", "//a/b/..");
656 assert_resolve_relative(&buf, "/a/b/c", "//a/Q/../b/x/y/../../c");
657 assert_resolve_relative(&buf, "/", "//a/b/../..");
658#endif
659
e579e0f7 660 git_str_dispose(&buf);
6d9a6c5c 661}
ba6f86eb
ET
662
663#define assert_common_dirlen(i, p, q) \
e579e0f7 664 cl_assert_equal_i((i), git_fs_path_common_dirlen((p), (q)));
ba6f86eb
ET
665
666void test_core_path__16_resolve_relative(void)
667{
668 assert_common_dirlen(0, "", "");
669 assert_common_dirlen(0, "", "bar.txt");
670 assert_common_dirlen(0, "foo.txt", "bar.txt");
671 assert_common_dirlen(0, "foo.txt", "");
672 assert_common_dirlen(0, "foo/bar.txt", "bar/foo.txt");
673 assert_common_dirlen(0, "foo/bar.txt", "../foo.txt");
674
675 assert_common_dirlen(1, "/one.txt", "/two.txt");
676 assert_common_dirlen(4, "foo/one.txt", "foo/two.txt");
677 assert_common_dirlen(5, "/foo/one.txt", "/foo/two.txt");
678
679 assert_common_dirlen(6, "a/b/c/foo.txt", "a/b/c/d/e/bar.txt");
680 assert_common_dirlen(7, "/a/b/c/foo.txt", "/a/b/c/d/e/bar.txt");
681}
ac3d33df 682
e579e0f7
MB
683static void fix_path(git_str *s)
684{
685#ifndef GIT_WIN32
686 GIT_UNUSED(s);
687#else
688 char* c;
689
690 for (c = s->ptr; *c; c++) {
691 if (*c == '/')
692 *c = '\\';
693 }
694#endif
695}
696
697void test_core_path__find_exe_in_path(void)
698{
699 char *orig_path;
700 git_str sandbox_path = GIT_STR_INIT;
701 git_str new_path = GIT_STR_INIT, full_path = GIT_STR_INIT,
702 dummy_path = GIT_STR_INIT;
703
704#ifdef GIT_WIN32
705 static const char *bogus_path_1 = "c:\\does\\not\\exist\\";
706 static const char *bogus_path_2 = "e:\\non\\existent";
707#else
708 static const char *bogus_path_1 = "/this/path/does/not/exist/";
709 static const char *bogus_path_2 = "/non/existent";
710#endif
711
712 orig_path = cl_getenv("PATH");
713
714 git_str_puts(&sandbox_path, clar_sandbox_path());
715 git_str_joinpath(&dummy_path, sandbox_path.ptr, "dummmmmmmy_libgit2_file");
716 cl_git_rewritefile(dummy_path.ptr, "this is a dummy file");
717
718 fix_path(&sandbox_path);
719 fix_path(&dummy_path);
720
721 cl_git_pass(git_str_printf(&new_path, "%s%c%s%c%s%c%s",
722 bogus_path_1, GIT_PATH_LIST_SEPARATOR,
723 orig_path, GIT_PATH_LIST_SEPARATOR,
724 sandbox_path.ptr, GIT_PATH_LIST_SEPARATOR,
725 bogus_path_2));
726
727 check_setenv("PATH", new_path.ptr);
728
729 cl_git_fail_with(GIT_ENOTFOUND, git_fs_path_find_executable(&full_path, "this_file_does_not_exist"));
730 cl_git_pass(git_fs_path_find_executable(&full_path, "dummmmmmmy_libgit2_file"));
731
732 cl_assert_equal_s(full_path.ptr, dummy_path.ptr);
733
734 git_str_dispose(&full_path);
735 git_str_dispose(&new_path);
736 git_str_dispose(&dummy_path);
737 git_str_dispose(&sandbox_path);
738 git__free(orig_path);
739}
740
741void test_core_path__validate_current_user_ownership(void)
ac3d33df 742{
e579e0f7
MB
743 bool is_cur;
744
745 cl_must_pass(p_mkdir("testdir", 0777));
746 cl_git_pass(git_fs_path_owner_is_current_user(&is_cur, "testdir"));
747 cl_assert_equal_i(is_cur, 1);
748
749 cl_git_rewritefile("testfile", "This is a test file.");
750 cl_git_pass(git_fs_path_owner_is_current_user(&is_cur, "testfile"));
751 cl_assert_equal_i(is_cur, 1);
752
753#ifdef GIT_WIN32
754 cl_git_pass(git_fs_path_owner_is_current_user(&is_cur, "C:\\"));
755 cl_assert_equal_i(is_cur, 0);
756
757 cl_git_fail(git_fs_path_owner_is_current_user(&is_cur, "c:\\path\\does\\not\\exist"));
758#else
759 cl_git_pass(git_fs_path_owner_is_current_user(&is_cur, "/"));
760 cl_assert_equal_i(is_cur, 0);
761
762 cl_git_fail(git_fs_path_owner_is_current_user(&is_cur, "/path/does/not/exist"));
763#endif
ac3d33df 764}