Commit 3644e98fd984c039d0c84b2311b410583739b6a5

nulltoken 2011-03-18T19:10:36

Fix detection of attempt to escape the root directory on Windows

diff --git a/src/fileops.c b/src/fileops.c
index 4123909..e440ea6 100644
--- a/src/fileops.c
+++ b/src/fileops.c
@@ -503,13 +503,15 @@ int gitfo_mkdir_recurs(const char *path, int mode)
 
 static int retrieve_previous_path_component_start(const char *path)
 {
-	int offset, len, start = 0;
-	
+	int offset, len, root_offset, start = 0;
+
+	root_offset = retrieve_path_root_offset(path);
+	if (root_offset > -1)
+		start += root_offset;
+
 	len = strlen(path);
 	offset = len - 1;
 
-	//TODO: Deal with Windows rooted path
-
 	/* Skip leading slash */
 	if (path[start] == '/')
 		start++;
@@ -518,7 +520,7 @@ static int retrieve_previous_path_component_start(const char *path)
 	if (path[offset] == '/')
 		offset--;
 
-	if (offset < 0)
+	if (offset < root_offset)
 		return GIT_ERROR;
 
 	while (offset > start && path[offset-1] != '/') {
diff --git a/tests/t00-core.c b/tests/t00-core.c
index d5fa07e..4cb1114 100644
--- a/tests/t00-core.c
+++ b/tests/t00-core.c
@@ -389,6 +389,37 @@ BEGIN_TEST(path6, "properly join path components for more than one path")
 	must_pass(ensure_joinpath_n("a", "b", "", "/c/d", "a/b/c/d"));
 END_TEST
 
+static int count_number_of_path_segments(const char *path)
+{
+	int number = 0;
+	char *current = (char *)path;
+
+	while (*current)
+	{
+		if (*current++ == '/')
+			number++;
+	}
+
+	assert (number > 0);
+
+	return --number;
+}
+
+BEGIN_TEST(path7, "prevent a path which escapes the root directory from being prettified")
+	char current_workdir[GIT_PATH_MAX];
+	char prettified[GIT_PATH_MAX];
+	int i = 0, number_to_escape;
+
+	must_pass(gitfo_getcwd(current_workdir, sizeof(current_workdir)));
+
+	number_to_escape = count_number_of_path_segments(current_workdir);
+
+	for (i = 0; i < number_to_escape + 1; i++)
+		git__joinpath(current_workdir, current_workdir, "../");
+
+	must_fail(gitfo_prettify_dir_path(prettified, sizeof(prettified), current_workdir));
+END_TEST
+
 typedef struct name_data {
 	int  count;  /* return count */
 	char *name;  /* filename     */
@@ -645,6 +676,7 @@ BEGIN_SUITE(core)
 	ADD_TEST(path4);
 	ADD_TEST(path5);
 	ADD_TEST(path6);
+	ADD_TEST(path7);
 
 	ADD_TEST(dirent0);
 	ADD_TEST(dirent1);