Fix detection of attempt to escape the root directory on Windows
1 2 3 4 5 6 7 8 9 10 11 12 13 14 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 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
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);