diff --git a/src/util.c b/src/util.c index fc1682f90..2f1bd2220 100644 --- a/src/util.c +++ b/src/util.c @@ -206,6 +206,7 @@ void git__joinpath_n(char *buffer_out, int count, ...) { va_list ap; int i; + char *buffer_start = buffer_out; va_start(ap, count); for (i = 0; i < count; ++i) { @@ -213,9 +214,12 @@ void git__joinpath_n(char *buffer_out, int count, ...) int len; path = va_arg(ap, const char *); - if (i > 0 && *path == '/') + if (i > 0 && *path == '/' && buffer_out > buffer_start && buffer_out[-1] == '/') path++; + if (!*path) + continue; + len = strlen(path); memcpy(buffer_out, path, len); buffer_out = buffer_out + len; diff --git a/tests/t00-core.c b/tests/t00-core.c index 216a19837..ad1f34b94 100644 --- a/tests/t00-core.c +++ b/tests/t00-core.c @@ -355,9 +355,11 @@ static int ensure_joinpath(const char *path_a, const char *path_b, const char *e } BEGIN_TEST("path", joinpath) - must_pass(ensure_joinpath("", "", "/")); - must_pass(ensure_joinpath("", "a", "/a")); + must_pass(ensure_joinpath("", "", "")); + must_pass(ensure_joinpath("", "a", "a")); + must_pass(ensure_joinpath("", "/a", "/a")); 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("/", "", "/")); @@ -367,6 +369,22 @@ BEGIN_TEST("path", joinpath) must_pass(ensure_joinpath("/a/", "/b/", "/a/b/")); END_TEST +static int ensure_joinpath_n(const char *path_a, const char *path_b, const char *path_c, const char *path_d, const char *expected_path) +{ + char joined_path[GIT_PATH_MAX]; + git__joinpath_n(joined_path, 4, path_a, path_b, path_c, path_d); + return strcmp(joined_path, expected_path) == 0 ? GIT_SUCCESS : GIT_ERROR; +} + +BEGIN_TEST("path", joinpath_n) + must_pass(ensure_joinpath_n("", "", "", "", "")); + must_pass(ensure_joinpath_n("", "a", "", "", "a/")); + must_pass(ensure_joinpath_n("a", "", "", "", "a/")); + must_pass(ensure_joinpath_n("", "", "", "a", "a")); + must_pass(ensure_joinpath_n("a", "b", "", "/c/d/", "a/b/c/d/")); + must_pass(ensure_joinpath_n("a", "b", "", "/c/d", "a/b/c/d")); +END_TEST + typedef struct name_data { int count; /* return count */ char *name; /* filename */ @@ -627,6 +645,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, "path", joinpath_n); ADD_TEST(suite, "dirent", dot); ADD_TEST(suite, "dirent", sub);