core.c 18.7 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
#include "clar_libgit2.h"
#include "path.h"

static void test_make_relative(
	const char *expected_path,
	const char *path,
	const char *parent,
	int expected_status)
{
	git_buf buf = GIT_BUF_INIT;
	git_buf_puts(&buf, path);
	cl_assert_equal_i(expected_status, git_path_make_relative(&buf, parent));
	cl_assert_equal_s(expected_path, buf.ptr);
14
	git_buf_dispose(&buf);
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
}

void test_path_core__make_relative(void)
{
	test_make_relative("foo.c", "/path/to/foo.c", "/path/to", 0);
	test_make_relative("bar/foo.c", "/path/to/bar/foo.c", "/path/to", 0);
	test_make_relative("foo.c", "/path/to/foo.c", "/path/to/", 0);

	test_make_relative("", "/path/to", "/path/to", 0);
	test_make_relative("", "/path/to", "/path/to/", 0);

	test_make_relative("../", "/path/to", "/path/to/foo", 0);

	test_make_relative("../foo.c", "/path/to/foo.c", "/path/to/bar", 0);
	test_make_relative("../bar/foo.c", "/path/to/bar/foo.c", "/path/to/baz", 0);

	test_make_relative("../../foo.c", "/path/to/foo.c", "/path/to/foo/bar", 0);
	test_make_relative("../../foo/bar.c", "/path/to/foo/bar.c", "/path/to/bar/foo", 0);

	test_make_relative("../../foo.c", "/foo.c", "/bar/foo", 0);

	test_make_relative("foo.c", "/path/to/foo.c", "/path/to/", 0);
	test_make_relative("../foo.c", "/path/to/foo.c", "/path/to/bar/", 0);

	test_make_relative("foo.c", "d:/path/to/foo.c", "d:/path/to", 0);

	test_make_relative("../foo", "/foo", "/bar", 0);
	test_make_relative("path/to/foo.c", "/path/to/foo.c", "/", 0);
	test_make_relative("../foo", "path/to/foo", "path/to/bar", 0);

	test_make_relative("/path/to/foo.c", "/path/to/foo.c", "d:/path/to", GIT_ENOTFOUND);
	test_make_relative("d:/path/to/foo.c", "d:/path/to/foo.c", "/path/to", GIT_ENOTFOUND);
	
	test_make_relative("/path/to/foo.c", "/path/to/foo.c", "not-a-rooted-path", GIT_ENOTFOUND);
	test_make_relative("not-a-rooted-path", "not-a-rooted-path", "/path/to", GIT_ENOTFOUND);
	
	test_make_relative("/path", "/path", "pathtofoo", GIT_ENOTFOUND);
	test_make_relative("path", "path", "pathtofoo", GIT_ENOTFOUND);
}
54 55 56

void test_path_core__isvalid_standard(void)
{
57 58 59
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/file.txt", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.file", 0, 0));
60 61 62 63
}

void test_path_core__isvalid_empty_dir_component(void)
{
64
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo//bar", 0, 0));
65 66

	/* leading slash */
67 68 69
	cl_assert_equal_b(false, git_path_isvalid(NULL, "/", 0, 0));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo", 0, 0));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "/foo/bar", 0, 0));
70 71

	/* trailing slash */
72 73
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/", 0, 0));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/", 0, 0));
74 75 76 77
}

void test_path_core__isvalid_dot_and_dotdot(void)
{
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "./foo", 0, 0));

	cl_assert_equal_b(true, git_path_isvalid(NULL, "..", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/..", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "../foo", 0, 0));

	cl_assert_equal_b(false, git_path_isvalid(NULL, ".", 0, GIT_PATH_REJECT_TRAVERSAL));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.", 0, GIT_PATH_REJECT_TRAVERSAL));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "./foo", 0, GIT_PATH_REJECT_TRAVERSAL));

	cl_assert_equal_b(false, git_path_isvalid(NULL, "..", 0, GIT_PATH_REJECT_TRAVERSAL));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/..", 0, GIT_PATH_REJECT_TRAVERSAL));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "../foo", 0, GIT_PATH_REJECT_TRAVERSAL));
97 98 99 100
}

void test_path_core__isvalid_dot_git(void)
{
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git/foo", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.git/bar", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.GIT/bar", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar/.Git", 0, 0));

	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git/foo", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.git/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/.GIT/bar", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar/.Git", 0, GIT_PATH_REJECT_DOT_GIT_LITERAL));

	cl_assert_equal_b(true, git_path_isvalid(NULL, "!git", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/!git", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "!git/bar", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/.tig", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".tig/bar", 0, 0));
121 122 123 124
}

void test_path_core__isvalid_backslash(void)
{
125 126 127
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo\\file.txt", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\file.txt", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar\\", 0, 0));
128

129 130 131
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\file.txt", 0, GIT_PATH_REJECT_BACKSLASH));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar\\", 0, GIT_PATH_REJECT_BACKSLASH));
132 133 134 135
}

void test_path_core__isvalid_trailing_dot(void)
{
136 137 138 139 140 141 142 143 144
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo.", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo...", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar.", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo./bar", 0, 0));

	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo.", 0, GIT_PATH_REJECT_TRAILING_DOT));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo...", 0, GIT_PATH_REJECT_TRAILING_DOT));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar.", 0, GIT_PATH_REJECT_TRAILING_DOT));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo./bar", 0, GIT_PATH_REJECT_TRAILING_DOT));
145 146 147 148
}

void test_path_core__isvalid_trailing_space(void)
{
149 150 151 152 153 154 155 156 157 158 159
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo ", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo   ", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar ", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, " ", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo /bar", 0, 0));

	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo ", 0, GIT_PATH_REJECT_TRAILING_SPACE));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo   ", 0, GIT_PATH_REJECT_TRAILING_SPACE));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar ", 0, GIT_PATH_REJECT_TRAILING_SPACE));
	cl_assert_equal_b(false, git_path_isvalid(NULL, " ", 0, GIT_PATH_REJECT_TRAILING_SPACE));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo /bar", 0, GIT_PATH_REJECT_TRAILING_SPACE));
160 161 162 163
}

void test_path_core__isvalid_trailing_colon(void)
{
164 165 166 167 168 169 170 171 172
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo/bar:", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ":", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "foo:/bar", 0, 0));

	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:", 0, GIT_PATH_REJECT_TRAILING_COLON));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo/bar:", 0, GIT_PATH_REJECT_TRAILING_COLON));
	cl_assert_equal_b(false, git_path_isvalid(NULL, ":", 0, GIT_PATH_REJECT_TRAILING_COLON));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "foo:/bar", 0, GIT_PATH_REJECT_TRAILING_COLON));
173 174
}

175
void test_path_core__isvalid_dotgit_ntfs(void)
176
{
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git ", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git.. .", 0, 0));

	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1 ", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "git~1.. .", 0, 0));

	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));

	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1 ", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "git~1.. .", 0, GIT_PATH_REJECT_DOT_GIT_NTFS));
196 197 198 199
}

void test_path_core__isvalid_dos_paths(void)
{
200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223
	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux.asdf\\zippy", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux:asdf\\foobar", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "con", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "prn", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "nul", 0, 0));

	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "aux:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "con", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "prn", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "nul", 0, GIT_PATH_REJECT_DOS_PATHS));

	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux1", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "auxn", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "aux\\foo", 0, GIT_PATH_REJECT_DOS_PATHS));
224 225 226 227
}

void test_path_core__isvalid_dos_paths_withnum(void)
{
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1.asdf\\zippy", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1:asdf\\foobar", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt1", 0, 0));

	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1.asdf\\zippy", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1:asdf\\foobar", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "com1/foo", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "lpt1", 0, GIT_PATH_REJECT_DOS_PATHS));

	cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "com0", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "com10", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "comn", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "com1\\foo", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt0", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "lpt10", 0, GIT_PATH_REJECT_DOS_PATHS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "lptn", 0, GIT_PATH_REJECT_DOS_PATHS));
255 256
}

257
void test_path_core__isvalid_nt_chars(void)
258
{
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277
	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\001foo", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\037bar", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf<bar", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf>foo", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf:foo", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf\"bar", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf|foo", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf?bar", 0, 0));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "asdf*bar", 0, 0));

	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\001foo", 0, GIT_PATH_REJECT_NT_CHARS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\037bar", 0, GIT_PATH_REJECT_NT_CHARS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf<bar", 0, GIT_PATH_REJECT_NT_CHARS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf>foo", 0, GIT_PATH_REJECT_NT_CHARS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf:foo", 0, GIT_PATH_REJECT_NT_CHARS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf\"bar", 0, GIT_PATH_REJECT_NT_CHARS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf|foo", 0, GIT_PATH_REJECT_NT_CHARS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf?bar", 0, GIT_PATH_REJECT_NT_CHARS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "asdf*bar", 0, GIT_PATH_REJECT_NT_CHARS));
278
}
279 280 281

void test_path_core__isvalid_dotgit_with_hfs_ignorables(void)
{
282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306
	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, ".git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, ".g\xe2\x80\x8eIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, ".\xe2\x80\x8fgIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xaa.gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS));

	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x80\xab.\xe2\x80\xacG\xe2\x80\xadI\xe2\x80\xaet", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xab.\xe2\x80\xaaG\xe2\x81\xabI\xe2\x80\xact", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(false, git_path_isvalid(NULL, "\xe2\x81\xad.\xe2\x80\xaeG\xef\xbb\xbfIT", 0, GIT_PATH_REJECT_DOT_GIT_HFS));

	cl_assert_equal_b(true, git_path_isvalid(NULL, ".", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".g", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, " .git", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "..git\xe2\x80\x8c", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\xe2\x80\x8dT.", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2\x80It", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".\xe2gIt", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, "\xe2\x80\xaa.gi", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x80\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".gi\x8dT", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".g\xe2i\x80T\x8e", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\x80\xbf", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
	cl_assert_equal_b(true, git_path_isvalid(NULL, ".git\xe2\xab\x81", 0, GIT_PATH_REJECT_DOT_GIT_HFS));
307
}
308 309 310 311 312 313 314 315 316 317 318 319 320 321

static void test_join_unrooted(
	const char *expected_result,
	ssize_t expected_rootlen,
	const char *path,
	const char *base)
{
	git_buf result = GIT_BUF_INIT;
	ssize_t root_at;

	cl_git_pass(git_path_join_unrooted(&result, path, base, &root_at));
	cl_assert_equal_s(expected_result, result.ptr);
	cl_assert_equal_i(expected_rootlen, root_at);

322
	git_buf_dispose(&result);
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
}

void test_path_core__join_unrooted(void)
{
	git_buf out = GIT_BUF_INIT;

	test_join_unrooted("foo", 0, "foo", NULL);
	test_join_unrooted("foo/bar", 0, "foo/bar", NULL);

	/* Relative paths have base prepended */
	test_join_unrooted("/foo/bar", 4, "bar", "/foo");
	test_join_unrooted("/foo/bar/foobar", 4, "bar/foobar", "/foo");
	test_join_unrooted("c:/foo/bar/foobar", 6, "bar/foobar", "c:/foo");
	test_join_unrooted("c:/foo/bar/foobar", 10, "foobar", "c:/foo/bar");

	/* Absolute paths are not prepended with base */
	test_join_unrooted("/foo", 0, "/foo", "/asdf");
	test_join_unrooted("/foo/bar", 0, "/foo/bar", "/asdf");

	/* Drive letter is given as root length on Windows */
	test_join_unrooted("c:/foo", 2, "c:/foo", "c:/asdf");
	test_join_unrooted("c:/foo/bar", 2, "c:/foo/bar", "c:/asdf");

	/* Base is returned when it's provided and is the prefix */
	test_join_unrooted("c:/foo/bar/foobar", 6, "c:/foo/bar/foobar", "c:/foo");
	test_join_unrooted("c:/foo/bar/foobar", 10, "c:/foo/bar/foobar", "c:/foo/bar");

	/* Trailing slash in the base is ignored */
	test_join_unrooted("c:/foo/bar/foobar", 6, "c:/foo/bar/foobar", "c:/foo/");

353
	git_buf_dispose(&out);
354
}