diff --git a/src/util.c b/src/util.c index e1f709962..67b74eeba 100644 --- a/src/util.c +++ b/src/util.c @@ -207,6 +207,8 @@ char *git__joinpath(const char *path_a, const char *path_b) int len_a, len_b; char *path_new; + assert(path_a && path_b); + len_a = strlen(path_a); len_b = strlen(path_b); @@ -216,7 +218,7 @@ char *git__joinpath(const char *path_a, const char *path_b) strcpy(path_new, path_a); - if (path_new[len_a - 1] != '/') + if (len_a > 0 && len_b > 0 && path_new[len_a - 1] != '/') path_new[len_a++] = '/'; if (path_b[0] == '/') diff --git a/tests/t00-core.c b/tests/t00-core.c index 7dd09955f..4a5df385f 100644 --- a/tests/t00-core.c +++ b/tests/t00-core.c @@ -342,6 +342,34 @@ BEGIN_TEST("path", dir_path_prettifying) must_fail(ensure_dir_path_normalized("/d1/.../d2", NULL)); END_TEST +static int ensure_joinpath(const char *path_a, const char *path_b, const char *expected_path) +{ + int error = GIT_SUCCESS; + char* joined_path; + + joined_path = git__joinpath(path_a, path_b); + if (joined_path == NULL) + return GIT_ERROR; + + if (strcmp(joined_path, expected_path)) + error = GIT_ERROR; + + return error; +} + +BEGIN_TEST("path", joinpath) + must_pass(ensure_joinpath("", "", "")); + must_pass(ensure_joinpath("", "a", "a")); + must_pass(ensure_joinpath("a", "", "a")); + must_pass(ensure_joinpath("a", "b", "a/b")); + must_pass(ensure_joinpath("/", "a", "/a")); + must_pass(ensure_joinpath("/", "", "/")); + must_pass(ensure_joinpath("/a", "/b", "/a/b")); + must_pass(ensure_joinpath("/a", "/b/", "/a/b/")); + must_pass(ensure_joinpath("/a/", "b/", "/a/b/")); + must_pass(ensure_joinpath("/a/", "/b/", "/a/b/")); +END_TEST + typedef struct name_data { int count; /* return count */ char *name; /* filename */ @@ -601,6 +629,7 @@ git_testsuite *libgit2_suite_core(void) ADD_TEST(suite, "path", file_path_prettifying); ADD_TEST(suite, "path", dir_path_prettifying); + ADD_TEST(suite, "path", joinpath); ADD_TEST(suite, "dirent", dot); ADD_TEST(suite, "dirent", sub);