diff --git a/src/fileops.c b/src/fileops.c index 4ed53bc97..41239091b 100644 --- a/src/fileops.c +++ b/src/fileops.c @@ -443,22 +443,29 @@ int gitfo_dirent( return GIT_SUCCESS; } + +int retrieve_path_root_offset(const char *path) +{ + int offset = 0; + #ifdef GIT_WIN32 -static int is_windows_rooted_path(const char *path) -{ /* Does the root of the path look like a windows drive ? */ if (isalpha(path[0]) && (path[1] == ':')) - return GIT_SUCCESS; + offset += 2; + +#endif + + if (*(path + offset) == '/') + return offset; return GIT_ERROR; } -#endif int gitfo_mkdir_recurs(const char *path, int mode) { - int error; + int error, root_path_offset; char *pp, *sp; char *path_copy = git__strdup(path); @@ -468,12 +475,9 @@ int gitfo_mkdir_recurs(const char *path, int mode) error = GIT_SUCCESS; pp = path_copy; -#ifdef GIT_WIN32 - - if (!is_windows_rooted_path(pp)) - pp += 2; /* Skip the drive name (eg. C: or D:) */ - -#endif + root_path_offset = retrieve_path_root_offset(pp); + if (root_path_offset > 0) + pp += root_path_offset; /* On Windows, will skip the drive name (eg. C: or D:) */ while (error == GIT_SUCCESS && (sp = strchr(pp, '/')) != 0) { if (sp != pp && gitfo_isdir(path_copy) < GIT_SUCCESS) { @@ -504,6 +508,8 @@ static int retrieve_previous_path_component_start(const char *path) len = strlen(path); offset = len - 1; + //TODO: Deal with Windows rooted path + /* Skip leading slash */ if (path[start] == '/') start++; @@ -522,15 +528,25 @@ static int retrieve_previous_path_component_start(const char *path) return offset; } -int gitfo_prettify_dir_path(char *buffer_out, const char *path) +int gitfo_prettify_dir_path(char *buffer_out, size_t size, const char *path) { - int len = 0, segment_len, only_dots; + int len = 0, segment_len, only_dots, root_path_offset, error = GIT_SUCCESS; char *current; const char *buffer_out_start, *buffer_end; - buffer_out_start = buffer_out; current = (char *)path; buffer_end = path + strlen(path); + buffer_out_start = buffer_out; + + root_path_offset = retrieve_path_root_offset(path); + if (root_path_offset < 0) { + error = gitfo_getcwd(buffer_out, size); + if (error < GIT_SUCCESS) + return error; + + len = strlen(buffer_out); + buffer_out += len; + } while (current < buffer_end) { /* Prevent multiple slashes from being added to the output */ @@ -543,7 +559,7 @@ int gitfo_prettify_dir_path(char *buffer_out, const char *path) segment_len = 0; /* Copy path segment to the output */ - while (current < buffer_end && *current !='/') + while (current < buffer_end && *current != '/') { only_dots &= (*current == '.'); *buffer_out++ = *current++; @@ -568,7 +584,9 @@ int gitfo_prettify_dir_path(char *buffer_out, const char *path) *buffer_out ='\0'; len = retrieve_previous_path_component_start(buffer_out_start); - if (len < GIT_SUCCESS) + + /* Are we escaping out of the root dir? */ + if (len < 0) return GIT_EINVALIDPATH; buffer_out = (char *)buffer_out_start + len; @@ -576,7 +594,7 @@ int gitfo_prettify_dir_path(char *buffer_out, const char *path) } /* Guard against potential multiple dot path traversal (cf http://cwe.mitre.org/data/definitions/33.html) */ - if (only_dots &&segment_len > 0) + if (only_dots && segment_len > 0) return GIT_EINVALIDPATH; *buffer_out++ = '/'; @@ -588,20 +606,24 @@ int gitfo_prettify_dir_path(char *buffer_out, const char *path) return GIT_SUCCESS; } -int gitfo_prettify_file_path(char *buffer_out, const char *path) +int gitfo_prettify_file_path(char *buffer_out, size_t size, const char *path) { int error, path_len, i; const char* pattern = "/.."; path_len = strlen(path); + /* Let's make sure the filename isn't empty nor a dot */ + if (path_len == 0 || (path_len == 1 && *path == '.')) + return GIT_EINVALIDPATH; + /* Let's make sure the filename doesn't end with "/", "/." or "/.." */ for (i = 1; path_len > i && i < 4; i++) { if (!strncmp(path + path_len - i, pattern, i)) return GIT_EINVALIDPATH; } - error = gitfo_prettify_dir_path(buffer_out, path); + error = gitfo_prettify_dir_path(buffer_out, size, path); if (error < GIT_SUCCESS) return error; diff --git a/src/fileops.h b/src/fileops.h index c2c038b26..ce236f608 100644 --- a/src/fileops.h +++ b/src/fileops.h @@ -163,12 +163,13 @@ extern int gitfo_getcwd(char *buffer_out, size_t size); * the file system perspective. * * @param buffer_out buffer to populate with the normalized path. + * @param size buffer size. * @param path directory path to clean up. * @return * - GIT_SUCCESS on success; * - GIT_ERROR when the input path is invalid or escapes the current directory. */ -int gitfo_prettify_dir_path(char *buffer_out, const char *path); +int gitfo_prettify_dir_path(char *buffer_out, size_t size, const char *path); /** * Clean up a provided absolute or relative file path. @@ -185,11 +186,13 @@ int gitfo_prettify_dir_path(char *buffer_out, const char *path); * the file system perspective. * * @param buffer_out buffer to populate with the normalized path. + * @param size buffer size. * @param path file path to clean up. * @return * - GIT_SUCCESS on success; * - GIT_ERROR when the input path is invalid or escapes the current directory. */ -int gitfo_prettify_file_path(char *buffer_out, const char *path); +int gitfo_prettify_file_path(char *buffer_out, size_t size, const char *path); +int retrieve_path_root_offset(const char *path); #endif /* INCLUDE_fileops_h__ */ diff --git a/src/repository.c b/src/repository.c index 132969402..91b95a881 100644 --- a/src/repository.c +++ b/src/repository.c @@ -66,7 +66,7 @@ static int assign_repository_dirs( if (git_dir == NULL) return GIT_ENOTFOUND; - error = gitfo_prettify_dir_path(path_aux, git_dir); + error = gitfo_prettify_dir_path(path_aux, sizeof(path_aux), git_dir); if (error < GIT_SUCCESS) return error; @@ -81,7 +81,7 @@ static int assign_repository_dirs( if (git_object_directory == NULL) git__joinpath(path_aux, repo->path_repository, GIT_OBJECTS_DIR); else { - error = gitfo_prettify_dir_path(path_aux, git_object_directory); + error = gitfo_prettify_dir_path(path_aux, sizeof(path_aux), git_object_directory); if (error < GIT_SUCCESS) return error; } @@ -95,7 +95,7 @@ static int assign_repository_dirs( if (git_work_tree == NULL) repo->is_bare = 1; else { - error = gitfo_prettify_dir_path(path_aux, git_work_tree); + error = gitfo_prettify_dir_path(path_aux, sizeof(path_aux), git_work_tree); if (error < GIT_SUCCESS) return error; @@ -108,7 +108,7 @@ static int assign_repository_dirs( if (git_index_file == NULL) git__joinpath(path_aux, repo->path_repository, GIT_INDEX_FILE); else { - error = gitfo_prettify_file_path(path_aux, git_index_file); + error = gitfo_prettify_file_path(path_aux, sizeof(path_aux), git_index_file); if (error < GIT_SUCCESS) return error; } @@ -403,7 +403,7 @@ static int repo_init_find_dir(repo_init *results, const char* path) char temp_path[GIT_PATH_MAX]; int error = GIT_SUCCESS; - error = gitfo_prettify_dir_path(temp_path, path); + error = gitfo_prettify_dir_path(temp_path, sizeof(temp_path), path); if (error < GIT_SUCCESS) return error; diff --git a/tests/t00-core.c b/tests/t00-core.c index 08e42ecf4..d5fa07eb4 100644 --- a/tests/t00-core.c +++ b/tests/t00-core.c @@ -151,187 +151,204 @@ BEGIN_TEST(path2, "get the latest component in a path") #undef TOPDIR_TEST END_TEST -typedef int (normalize_path)(char *, const char *); +typedef int (normalize_path)(char *, size_t, const char *); -static int ensure_normalized(const char *input_path, const char *expected_path, normalize_path normalizer) +/* Assert flags */ +#define CWD_AS_PREFIX 1 +#define PATH_AS_SUFFIX 2 +#define ROOTED_PATH 4 + +static int ensure_normalized(const char *input_path, const char *expected_path, normalize_path normalizer, int assert_flags) { int error = GIT_SUCCESS; char buffer_out[GIT_PATH_MAX]; + char current_workdir[GIT_PATH_MAX]; - error = normalizer(buffer_out, input_path); + error = gitfo_getcwd(current_workdir, sizeof(current_workdir)); + if (error < GIT_SUCCESS) + return error; + + error = normalizer(buffer_out, sizeof(buffer_out), input_path); if (error < GIT_SUCCESS) return error; if (expected_path == NULL) return error; - if (strcmp(buffer_out, expected_path)) - error = GIT_ERROR; + if ((assert_flags & PATH_AS_SUFFIX) != 0) + if (git__suffixcmp(buffer_out, expected_path)) + return GIT_ERROR; + + if ((assert_flags & CWD_AS_PREFIX) != 0) + if (git__prefixcmp(buffer_out, current_workdir)) + return GIT_ERROR; + + if ((assert_flags & ROOTED_PATH) != 0) { + error = strcmp(expected_path, buffer_out); + } return error; } -static int ensure_dir_path_normalized(const char *input_path, const char *expected_path) +static int ensure_dir_path_normalized(const char *input_path, const char *expected_path, int assert_flags) { - return ensure_normalized(input_path, expected_path, gitfo_prettify_dir_path); + return ensure_normalized(input_path, expected_path, gitfo_prettify_dir_path, assert_flags); } -static int ensure_file_path_normalized(const char *input_path, const char *expected_path) +static int ensure_file_path_normalized(const char *input_path, const char *expected_path, int assert_flags) { - return ensure_normalized(input_path, expected_path, gitfo_prettify_file_path); + return ensure_normalized(input_path, expected_path, gitfo_prettify_file_path, assert_flags); } BEGIN_TEST(path3, "prettify and validate a path to a file") - must_pass(ensure_file_path_normalized("a", "a")); - must_pass(ensure_file_path_normalized("./testrepo.git", "testrepo.git")); - must_pass(ensure_file_path_normalized("./.git", ".git")); - must_pass(ensure_file_path_normalized("./git.", "git.")); - must_fail(ensure_file_path_normalized("git./", NULL)); - must_fail(ensure_file_path_normalized("", NULL)); - must_fail(ensure_file_path_normalized(".", NULL)); - must_fail(ensure_file_path_normalized("./", NULL)); - must_fail(ensure_file_path_normalized("./.", NULL)); - must_fail(ensure_file_path_normalized("./..", NULL)); - must_fail(ensure_file_path_normalized("../.", NULL)); - must_fail(ensure_file_path_normalized("./.././/", NULL)); - must_fail(ensure_file_path_normalized("dir/..", NULL)); - must_fail(ensure_file_path_normalized("dir/sub/../..", NULL)); - must_fail(ensure_file_path_normalized("dir/sub/..///..", NULL)); - must_fail(ensure_file_path_normalized("dir/sub///../..", NULL)); - must_fail(ensure_file_path_normalized("dir/sub///..///..", NULL)); - must_fail(ensure_file_path_normalized("dir/sub/../../..", NULL)); - must_pass(ensure_file_path_normalized("dir", "dir")); - must_fail(ensure_file_path_normalized("dir//", NULL)); - must_pass(ensure_file_path_normalized("./dir", "dir")); - must_fail(ensure_file_path_normalized("dir/.", NULL)); - must_fail(ensure_file_path_normalized("dir///./", NULL)); - must_fail(ensure_file_path_normalized("dir/sub/..", NULL)); - must_fail(ensure_file_path_normalized("dir//sub/..",NULL)); - must_fail(ensure_file_path_normalized("dir//sub/../", NULL)); - must_fail(ensure_file_path_normalized("dir/sub/../", NULL)); - must_fail(ensure_file_path_normalized("dir/sub/../.", NULL)); - must_fail(ensure_file_path_normalized("dir/s1/../s2/", NULL)); - must_fail(ensure_file_path_normalized("d1/s1///s2/..//../s3/", NULL)); - must_pass(ensure_file_path_normalized("d1/s1//../s2/../../d2", "d2")); - must_fail(ensure_file_path_normalized("dir/sub/../", NULL)); - must_fail(ensure_file_path_normalized("....", NULL)); - must_fail(ensure_file_path_normalized("...", NULL)); - must_fail(ensure_file_path_normalized("./...", NULL)); - must_fail(ensure_file_path_normalized("d1/...", NULL)); - must_fail(ensure_file_path_normalized("d1/.../", NULL)); - must_fail(ensure_file_path_normalized("d1/.../d2", NULL)); + must_pass(ensure_file_path_normalized("a", "a", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_file_path_normalized("./testrepo.git", "testrepo.git", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_file_path_normalized("./.git", ".git", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_file_path_normalized("./git.", "git.", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_fail(ensure_file_path_normalized("git./", NULL, 0)); + must_fail(ensure_file_path_normalized("", NULL, 0)); + must_fail(ensure_file_path_normalized(".", NULL, 0)); + must_fail(ensure_file_path_normalized("./", NULL, 0)); + must_fail(ensure_file_path_normalized("./.", NULL, 0)); + must_fail(ensure_file_path_normalized("./..", NULL, 0)); + must_fail(ensure_file_path_normalized("../.", NULL, 0)); + must_fail(ensure_file_path_normalized("./.././/", NULL, 0)); + must_fail(ensure_file_path_normalized("dir/..", NULL, 0)); + must_fail(ensure_file_path_normalized("dir/sub/../..", NULL, 0)); + must_fail(ensure_file_path_normalized("dir/sub/..///..", NULL, 0)); + must_fail(ensure_file_path_normalized("dir/sub///../..", NULL, 0)); + must_fail(ensure_file_path_normalized("dir/sub///..///..", NULL, 0)); + must_fail(ensure_file_path_normalized("dir/sub/../../..", NULL, 0)); + must_pass(ensure_file_path_normalized("dir", "dir", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_fail(ensure_file_path_normalized("dir//", NULL, 0)); + must_pass(ensure_file_path_normalized("./dir", "dir", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_fail(ensure_file_path_normalized("dir/.", NULL, 0)); + must_fail(ensure_file_path_normalized("dir///./", NULL, 0)); + must_fail(ensure_file_path_normalized("dir/sub/..", NULL, 0)); + must_fail(ensure_file_path_normalized("dir//sub/..",NULL, 0)); + must_fail(ensure_file_path_normalized("dir//sub/../", NULL, 0)); + must_fail(ensure_file_path_normalized("dir/sub/../", NULL, 0)); + must_fail(ensure_file_path_normalized("dir/sub/../.", NULL, 0)); + must_fail(ensure_file_path_normalized("dir/s1/../s2/", NULL, 0)); + must_fail(ensure_file_path_normalized("d1/s1///s2/..//../s3/", NULL, 0)); + must_pass(ensure_file_path_normalized("d1/s1//../s2/../../d2", "d2", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_fail(ensure_file_path_normalized("dir/sub/../", NULL, 0)); + must_pass(ensure_file_path_normalized("../../a/../../b/c/d/../../e", "b/e", PATH_AS_SUFFIX)); + must_fail(ensure_file_path_normalized("....", NULL, 0)); + must_fail(ensure_file_path_normalized("...", NULL, 0)); + must_fail(ensure_file_path_normalized("./...", NULL, 0)); + must_fail(ensure_file_path_normalized("d1/...", NULL, 0)); + must_fail(ensure_file_path_normalized("d1/.../", NULL, 0)); + must_fail(ensure_file_path_normalized("d1/.../d2", NULL, 0)); - must_pass(ensure_file_path_normalized("/a", "/a")); - must_pass(ensure_file_path_normalized("/./testrepo.git", "/testrepo.git")); - must_pass(ensure_file_path_normalized("/./.git", "/.git")); - must_pass(ensure_file_path_normalized("/./git.", "/git.")); - must_fail(ensure_file_path_normalized("/git./", NULL)); - must_fail(ensure_file_path_normalized("/", NULL)); - must_fail(ensure_file_path_normalized("/.", NULL)); - must_fail(ensure_file_path_normalized("/./", NULL)); - must_fail(ensure_file_path_normalized("/./.", NULL)); - must_fail(ensure_file_path_normalized("/./..", NULL)); - must_fail(ensure_file_path_normalized("/../.", NULL)); - must_fail(ensure_file_path_normalized("/./.././/", NULL)); - must_fail(ensure_file_path_normalized("/dir/..", NULL)); - must_fail(ensure_file_path_normalized("/dir/sub/../..", NULL)); - must_fail(ensure_file_path_normalized("/dir/sub/..///..", NULL)); - must_fail(ensure_file_path_normalized("/dir/sub///../..", NULL)); - must_fail(ensure_file_path_normalized("/dir/sub///..///..", NULL)); - must_fail(ensure_file_path_normalized("/dir/sub/../../..", NULL)); - must_pass(ensure_file_path_normalized("/dir", "/dir")); - must_fail(ensure_file_path_normalized("/dir//", NULL)); - must_pass(ensure_file_path_normalized("/./dir", "/dir")); - must_fail(ensure_file_path_normalized("/dir/.", NULL)); - must_fail(ensure_file_path_normalized("/dir///./", NULL)); - must_fail(ensure_file_path_normalized("/dir/sub/..", NULL)); - must_fail(ensure_file_path_normalized("/dir//sub/..",NULL)); - must_fail(ensure_file_path_normalized("/dir//sub/../", NULL)); - must_fail(ensure_file_path_normalized("/dir/sub/../", NULL)); - must_fail(ensure_file_path_normalized("/dir/sub/../.", NULL)); - must_fail(ensure_file_path_normalized("/dir/s1/../s2/", NULL)); - must_fail(ensure_file_path_normalized("/d1/s1///s2/..//../s3/", NULL)); - must_pass(ensure_file_path_normalized("/d1/s1//../s2/../../d2", "/d2")); - must_fail(ensure_file_path_normalized("/dir/sub/../", NULL)); - must_fail(ensure_file_path_normalized("/....", NULL)); - must_fail(ensure_file_path_normalized("/...", NULL)); - must_fail(ensure_file_path_normalized("/./...", NULL)); - must_fail(ensure_file_path_normalized("/d1/...", NULL)); - must_fail(ensure_file_path_normalized("/d1/.../", NULL)); - must_fail(ensure_file_path_normalized("/d1/.../d2", NULL)); + must_pass(ensure_file_path_normalized("/a", "/a", ROOTED_PATH)); + must_pass(ensure_file_path_normalized("/./testrepo.git", "/testrepo.git", ROOTED_PATH)); + must_pass(ensure_file_path_normalized("/./.git", "/.git", ROOTED_PATH)); + must_pass(ensure_file_path_normalized("/./git.", "/git.", ROOTED_PATH)); + must_fail(ensure_file_path_normalized("/git./", NULL, 0)); + must_fail(ensure_file_path_normalized("/", NULL, 0)); + must_fail(ensure_file_path_normalized("/.", NULL, 0)); + must_fail(ensure_file_path_normalized("/./", NULL, 0)); + must_fail(ensure_file_path_normalized("/./.", NULL, 0)); + must_fail(ensure_file_path_normalized("/./..", NULL, 0)); + must_fail(ensure_file_path_normalized("/../.", NULL, 0)); + must_fail(ensure_file_path_normalized("/./.././/", NULL, 0)); + must_fail(ensure_file_path_normalized("/dir/..", NULL, 0)); + must_fail(ensure_file_path_normalized("/dir/sub/../..", NULL, 0)); + must_fail(ensure_file_path_normalized("/dir/sub/..///..", NULL, 0)); + must_fail(ensure_file_path_normalized("/dir/sub///../..", NULL, 0)); + must_fail(ensure_file_path_normalized("/dir/sub///..///..", NULL, 0)); + must_fail(ensure_file_path_normalized("/dir/sub/../../..", NULL, 0)); + must_pass(ensure_file_path_normalized("/dir", "/dir", 0)); + must_fail(ensure_file_path_normalized("/dir//", NULL, 0)); + must_pass(ensure_file_path_normalized("/./dir", "/dir", 0)); + must_fail(ensure_file_path_normalized("/dir/.", NULL, 0)); + must_fail(ensure_file_path_normalized("/dir///./", NULL, 0)); + must_fail(ensure_file_path_normalized("/dir/sub/..", NULL, 0)); + must_fail(ensure_file_path_normalized("/dir//sub/..",NULL, 0)); + must_fail(ensure_file_path_normalized("/dir//sub/../", NULL, 0)); + must_fail(ensure_file_path_normalized("/dir/sub/../", NULL, 0)); + must_fail(ensure_file_path_normalized("/dir/sub/../.", NULL, 0)); + must_fail(ensure_file_path_normalized("/dir/s1/../s2/", NULL, 0)); + must_fail(ensure_file_path_normalized("/d1/s1///s2/..//../s3/", NULL, 0)); + must_pass(ensure_file_path_normalized("/d1/s1//../s2/../../d2", "/d2", 0)); + must_fail(ensure_file_path_normalized("/dir/sub/../", NULL, 0)); + must_fail(ensure_file_path_normalized("/....", NULL, 0)); + must_fail(ensure_file_path_normalized("/...", NULL, 0)); + must_fail(ensure_file_path_normalized("/./...", NULL, 0)); + must_fail(ensure_file_path_normalized("/d1/...", NULL, 0)); + must_fail(ensure_file_path_normalized("/d1/.../", NULL, 0)); + must_fail(ensure_file_path_normalized("/d1/.../d2", NULL, 0)); END_TEST BEGIN_TEST(path4, "validate and prettify a path to a folder") - must_pass(ensure_dir_path_normalized("./testrepo.git", "testrepo.git/")); - must_pass(ensure_dir_path_normalized("./.git", ".git/")); - must_pass(ensure_dir_path_normalized("./git.", "git./")); - must_pass(ensure_dir_path_normalized("git./", "git./")); - must_pass(ensure_dir_path_normalized("", "")); - must_pass(ensure_dir_path_normalized(".", "")); - must_pass(ensure_dir_path_normalized("./", "")); - must_pass(ensure_dir_path_normalized("./.", "")); - must_fail(ensure_dir_path_normalized("./..", NULL)); - must_fail(ensure_dir_path_normalized("../.", NULL)); - must_fail(ensure_dir_path_normalized("./.././/", NULL)); - must_pass(ensure_dir_path_normalized("dir/..", "")); - must_pass(ensure_dir_path_normalized("dir/sub/../..", "")); - must_pass(ensure_dir_path_normalized("dir/sub/..///..", "")); - must_pass(ensure_dir_path_normalized("dir/sub///../..", "")); - must_pass(ensure_dir_path_normalized("dir/sub///..///..", "")); - must_fail(ensure_dir_path_normalized("dir/sub/../../..", NULL)); - must_pass(ensure_dir_path_normalized("dir", "dir/")); - must_pass(ensure_dir_path_normalized("dir//", "dir/")); - must_pass(ensure_dir_path_normalized("./dir", "dir/")); - must_pass(ensure_dir_path_normalized("dir/.", "dir/")); - must_pass(ensure_dir_path_normalized("dir///./", "dir/")); - must_pass(ensure_dir_path_normalized("dir/sub/..", "dir/")); - must_pass(ensure_dir_path_normalized("dir//sub/..", "dir/")); - must_pass(ensure_dir_path_normalized("dir//sub/../", "dir/")); - must_pass(ensure_dir_path_normalized("dir/sub/../", "dir/")); - must_pass(ensure_dir_path_normalized("dir/sub/../.", "dir/")); - must_pass(ensure_dir_path_normalized("dir/s1/../s2/", "dir/s2/")); - must_pass(ensure_dir_path_normalized("d1/s1///s2/..//../s3/", "d1/s3/")); - must_pass(ensure_dir_path_normalized("d1/s1//../s2/../../d2", "d2/")); - must_pass(ensure_dir_path_normalized("dir/sub/../", "dir/")); - must_fail(ensure_dir_path_normalized("....", NULL)); - must_fail(ensure_dir_path_normalized("...", NULL)); - must_fail(ensure_dir_path_normalized("./...", NULL)); - must_fail(ensure_dir_path_normalized("d1/...", NULL)); - must_fail(ensure_dir_path_normalized("d1/.../", NULL)); - must_fail(ensure_dir_path_normalized("d1/.../d2", NULL)); + must_pass(ensure_dir_path_normalized("./testrepo.git", "testrepo.git/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("./.git", ".git/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("./git.", "git./", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("git./", "git./", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("", "", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized(".", "", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("./", "", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("./.", "", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir/..", "", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir/sub/../..", "", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir/sub/..///..", "", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir/sub///../..", "", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir/sub///..///..", "", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir", "dir/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir//", "dir/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("./dir", "dir/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir/.", "dir/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir///./", "dir/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir/sub/..", "dir/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir//sub/..", "dir/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir//sub/../", "dir/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir/sub/../", "dir/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir/sub/../.", "dir/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir/s1/../s2/", "dir/s2/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("d1/s1///s2/..//../s3/", "d1/s3/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("d1/s1//../s2/../../d2", "d2/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("dir/sub/../", "dir/", CWD_AS_PREFIX | PATH_AS_SUFFIX)); + must_pass(ensure_dir_path_normalized("../../a/../../b/c/d/../../e", "b/e/", PATH_AS_SUFFIX)); + must_fail(ensure_dir_path_normalized("....", NULL, 0)); + must_fail(ensure_dir_path_normalized("...", NULL, 0)); + must_fail(ensure_dir_path_normalized("./...", NULL, 0)); + must_fail(ensure_dir_path_normalized("d1/...", NULL, 0)); + must_fail(ensure_dir_path_normalized("d1/.../", NULL, 0)); + must_fail(ensure_dir_path_normalized("d1/.../d2", NULL, 0)); - must_pass(ensure_dir_path_normalized("/./testrepo.git", "/testrepo.git/")); - must_pass(ensure_dir_path_normalized("/./.git", "/.git/")); - must_pass(ensure_dir_path_normalized("/./git.", "/git./")); - must_pass(ensure_dir_path_normalized("/git./", "/git./")); - must_pass(ensure_dir_path_normalized("/", "/")); - must_pass(ensure_dir_path_normalized("//", "/")); - must_pass(ensure_dir_path_normalized("///", "/")); - must_pass(ensure_dir_path_normalized("/.", "/")); - must_pass(ensure_dir_path_normalized("/./", "/")); - must_fail(ensure_dir_path_normalized("/./..", NULL)); - must_fail(ensure_dir_path_normalized("/../.", NULL)); - must_fail(ensure_dir_path_normalized("/./.././/", NULL)); - must_pass(ensure_dir_path_normalized("/dir/..", "/")); - must_pass(ensure_dir_path_normalized("/dir/sub/../..", "/")); - must_fail(ensure_dir_path_normalized("/dir/sub/../../..", NULL)); - must_pass(ensure_dir_path_normalized("/dir", "/dir/")); - must_pass(ensure_dir_path_normalized("/dir//", "/dir/")); - must_pass(ensure_dir_path_normalized("/./dir", "/dir/")); - must_pass(ensure_dir_path_normalized("/dir/.", "/dir/")); - must_pass(ensure_dir_path_normalized("/dir///./", "/dir/")); - must_pass(ensure_dir_path_normalized("/dir//sub/..", "/dir/")); - must_pass(ensure_dir_path_normalized("/dir/sub/../", "/dir/")); - must_pass(ensure_dir_path_normalized("//dir/sub/../.", "/dir/")); - must_pass(ensure_dir_path_normalized("/dir/s1/../s2/", "/dir/s2/")); - must_pass(ensure_dir_path_normalized("/d1/s1///s2/..//../s3/", "/d1/s3/")); - must_pass(ensure_dir_path_normalized("/d1/s1//../s2/../../d2", "/d2/")); - must_fail(ensure_dir_path_normalized("/....", NULL)); - must_fail(ensure_dir_path_normalized("/...", NULL)); - must_fail(ensure_dir_path_normalized("/./...", NULL)); - must_fail(ensure_dir_path_normalized("/d1/...", NULL)); - must_fail(ensure_dir_path_normalized("/d1/.../", NULL)); - must_fail(ensure_dir_path_normalized("/d1/.../d2", NULL)); + must_pass(ensure_dir_path_normalized("/./testrepo.git", "/testrepo.git/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/./.git", "/.git/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/./git.", "/git./", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/git./", "/git./", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/", "/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("//", "/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("///", "/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/.", "/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/./", "/", ROOTED_PATH)); + must_fail(ensure_dir_path_normalized("/./..", NULL, 0)); + must_fail(ensure_dir_path_normalized("/../.", NULL, 0)); + must_fail(ensure_dir_path_normalized("/./.././/", NULL, 0)); + must_pass(ensure_dir_path_normalized("/dir/..", "/", 0)); + must_pass(ensure_dir_path_normalized("/dir/sub/../..", "/", 0)); + must_fail(ensure_dir_path_normalized("/dir/sub/../../..", NULL, 0)); + must_pass(ensure_dir_path_normalized("/dir", "/dir/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/dir//", "/dir/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/./dir", "/dir/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/dir/.", "/dir/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/dir///./", "/dir/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/dir//sub/..", "/dir/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/dir/sub/../", "/dir/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("//dir/sub/../.", "/dir/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/dir/s1/../s2/", "/dir/s2/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/d1/s1///s2/..//../s3/", "/d1/s3/", ROOTED_PATH)); + must_pass(ensure_dir_path_normalized("/d1/s1//../s2/../../d2", "/d2/", ROOTED_PATH)); + must_fail(ensure_dir_path_normalized("/....", NULL, 0)); + must_fail(ensure_dir_path_normalized("/...", NULL, 0)); + must_fail(ensure_dir_path_normalized("/./...", NULL, 0)); + must_fail(ensure_dir_path_normalized("/d1/...", NULL, 0)); + must_fail(ensure_dir_path_normalized("/d1/.../", NULL, 0)); + must_fail(ensure_dir_path_normalized("/d1/.../d2", NULL, 0)); END_TEST static int ensure_joinpath(const char *path_a, const char *path_b, const char *expected_path) diff --git a/tests/t12-repo.c b/tests/t12-repo.c index 8b39e3902..2c7f1316a 100644 --- a/tests/t12-repo.c +++ b/tests/t12-repo.c @@ -113,22 +113,18 @@ static int ensure_repository_init( return GIT_ERROR; if (repo->path_workdir != NULL || expected_working_directory != NULL) { - if (strcmp(repo->path_workdir, expected_working_directory) != 0) - //return GIT_ERROR; + if (git__suffixcmp(repo->path_workdir, expected_working_directory) != 0) goto cleanup; } - if (strcmp(repo->path_odb, path_odb) != 0) - //return GIT_ERROR; + if (git__suffixcmp(repo->path_odb, path_odb) != 0) goto cleanup; - if (strcmp(repo->path_repository, expected_path_repository) != 0) - //return GIT_ERROR; + if (git__suffixcmp(repo->path_repository, expected_path_repository) != 0) goto cleanup; if (repo->path_index != NULL || expected_path_index != NULL) { - if (strcmp(repo->path_index, expected_path_index) != 0) - //return GIT_ERROR; + if (git__suffixcmp(repo->path_index, expected_path_index) != 0) goto cleanup; } @@ -170,18 +166,18 @@ BEGIN_TEST(init2, "Initialize a bare repo with a relative path escaping out of t must_pass(gitfo_getcwd(current_workdir, sizeof(current_workdir))); - git__joinpath(path_repository, current_workdir, "a/b/c/"); + git__joinpath(path_repository, TEMP_REPO_FOLDER, "a/b/c/"); must_pass(gitfo_mkdir_recurs(path_repository, mode)); must_pass(chdir(path_repository)); must_pass(git_repository_init(&repo, "../d/e.git", 1)); + must_pass(git__suffixcmp(repo->path_repository, "/a/b/d/e.git/")); + git_repository_free(repo); must_pass(chdir(current_workdir)); - - git__joinpath(path_repository, current_workdir, "a/"); - must_pass(rmdir_recurs(path_repository)); + rmdir_recurs(TEMP_REPO_FOLDER); END_TEST BEGIN_SUITE(repository)