Commit 669db21b288dc06781a35c4516aa19bac84800f6

nulltoken 2011-02-28T22:21:18

Slightly changed the behavior of git__joinpath() and git__joinpath_n().

diff --git a/src/util.c b/src/util.c
index fc1682f..2f1bd22 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 216a198..ad1f34b 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);