Commit 618818dc by nulltoken Committed by Vicent Marti

Added git_prettify_file_path().

parent 4581c22a
...@@ -456,3 +456,30 @@ int git_prettify_dir_path(char *buffer_out, const char *path) ...@@ -456,3 +456,30 @@ int git_prettify_dir_path(char *buffer_out, const char *path)
return GIT_SUCCESS; return GIT_SUCCESS;
} }
int git_prettify_file_path(char *buffer_out, const char *path)
{
int error, path_len, i;
const char* pattern = "/..";
path_len = strlen(path);
/* 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_ERROR;
}
error = git_prettify_dir_path(buffer_out, path);
if (error < GIT_SUCCESS)
return error;
path_len = strlen(buffer_out);
if (path_len < 2)
return GIT_ERROR;
/* Remove the trailing slash */
buffer_out[path_len - 1] = '\0';
return GIT_SUCCESS;
}
...@@ -155,4 +155,26 @@ extern int gitfo_close_cached(gitfo_cache *ioc); ...@@ -155,4 +155,26 @@ extern int gitfo_close_cached(gitfo_cache *ioc);
*/ */
GIT_EXTERN(int) git_prettify_dir_path(char *buffer_out, const char *path); GIT_EXTERN(int) git_prettify_dir_path(char *buffer_out, const char *path);
/**
* Clean up a provided absolute or relative file path.
*
* This prettification relies on basic operations such as coalescing
* multiple forward slashes into a single slash, removing '.' and
* './' current directory segments, and removing parent directory
* whenever '..' is encountered.
*
* For instance, this will turn "d1/s1///s2/..//../s3" into "d1/s3".
*
* This only performs a string based analysis of the path.
* No checks are done to make sure the path actually makes sense from
* the file system perspective.
*
* @param buffer_out buffer to populate with the normalized path.
* @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.
*/
GIT_EXTERN(int) git_prettify_file_path(char *buffer_out, const char *path);
#endif /* INCLUDE_fileops_h__ */ #endif /* INCLUDE_fileops_h__ */
#include "test_lib.h" #include "test_lib.h"
#include "fileops.h" #include "fileops.h"
static int ensure_normalized(const char *input_path, const char *expected_path) typedef int (normalize_path)(char *, const char *);
static int ensure_normalized(const char *input_path, const char *expected_path, normalize_path normalizer)
{ {
int error = GIT_SUCCESS; int error = GIT_SUCCESS;
char buffer_out[GIT_PATH_MAX]; char buffer_out[GIT_PATH_MAX];
error = git_prettify_dir_path(buffer_out, input_path); error = normalizer(buffer_out, input_path);
if (error < GIT_SUCCESS) if (error < GIT_SUCCESS)
return error; return error;
...@@ -19,75 +21,165 @@ static int ensure_normalized(const char *input_path, const char *expected_path) ...@@ -19,75 +21,165 @@ static int ensure_normalized(const char *input_path, const char *expected_path)
return error; return error;
} }
BEGIN_TEST(path_prettifying) static int ensure_dir_path_normalized(const char *input_path, const char *expected_path)
must_pass(ensure_normalized("./testrepo.git", "testrepo.git/")); {
must_pass(ensure_normalized("./.git", ".git/")); return ensure_normalized(input_path, expected_path, git_prettify_dir_path);
must_pass(ensure_normalized("./git.", "git./")); }
must_pass(ensure_normalized("git./", "git./"));
must_pass(ensure_normalized("", "")); static int ensure_file_path_normalized(const char *input_path, const char *expected_path)
must_pass(ensure_normalized(".", "")); {
must_pass(ensure_normalized("./", "")); return ensure_normalized(input_path, expected_path, git_prettify_file_path);
must_pass(ensure_normalized("./.", "")); }
must_fail(ensure_normalized("./..", NULL));
must_fail(ensure_normalized("../.", NULL)); BEGIN_TEST(file_path_prettifying)
must_fail(ensure_normalized("./.././/", NULL)); must_pass(ensure_file_path_normalized("a", "a"));
must_pass(ensure_normalized("dir/..", "")); must_pass(ensure_file_path_normalized("./testrepo.git", "testrepo.git"));
must_pass(ensure_normalized("dir/sub/../..", "")); must_pass(ensure_file_path_normalized("./.git", ".git"));
must_pass(ensure_normalized("dir/sub/..///..", "")); must_pass(ensure_file_path_normalized("./git.", "git."));
must_pass(ensure_normalized("dir/sub///../..", "")); must_fail(ensure_file_path_normalized("git./", NULL));
must_pass(ensure_normalized("dir/sub///..///..", "")); must_fail(ensure_file_path_normalized("", NULL));
must_fail(ensure_normalized("dir/sub/../../..", NULL)); must_fail(ensure_file_path_normalized(".", NULL));
must_pass(ensure_normalized("dir", "dir/")); must_fail(ensure_file_path_normalized("./", NULL));
must_pass(ensure_normalized("dir//", "dir/")); must_fail(ensure_file_path_normalized("./.", NULL));
must_pass(ensure_normalized("./dir", "dir/")); must_fail(ensure_file_path_normalized("./..", NULL));
must_pass(ensure_normalized("dir/.", "dir/")); must_fail(ensure_file_path_normalized("../.", NULL));
must_pass(ensure_normalized("dir///./", "dir/")); must_fail(ensure_file_path_normalized("./.././/", NULL));
must_pass(ensure_normalized("dir/sub/..", "dir/")); must_fail(ensure_file_path_normalized("dir/..", NULL));
must_pass(ensure_normalized("dir//sub/..", "dir/")); must_fail(ensure_file_path_normalized("dir/sub/../..", NULL));
must_pass(ensure_normalized("dir//sub/../", "dir/")); must_fail(ensure_file_path_normalized("dir/sub/..///..", NULL));
must_pass(ensure_normalized("dir/sub/../", "dir/")); must_fail(ensure_file_path_normalized("dir/sub///../..", NULL));
must_pass(ensure_normalized("dir/sub/../.", "dir/")); must_fail(ensure_file_path_normalized("dir/sub///..///..", NULL));
must_pass(ensure_normalized("dir/s1/../s2/", "dir/s2/")); must_fail(ensure_file_path_normalized("dir/sub/../../..", NULL));
must_pass(ensure_normalized("d1/s1///s2/..//../s3/", "d1/s3/")); must_pass(ensure_file_path_normalized("dir", "dir"));
must_pass(ensure_normalized("d1/s1//../s2/../../d2", "d2/")); must_fail(ensure_file_path_normalized("dir//", NULL));
must_pass(ensure_normalized("dir/sub/../", "dir/")); must_pass(ensure_file_path_normalized("./dir", "dir"));
must_fail(ensure_normalized("....", NULL)); must_fail(ensure_file_path_normalized("dir/.", NULL));
must_fail(ensure_normalized("...", NULL)); must_fail(ensure_file_path_normalized("dir///./", NULL));
must_fail(ensure_normalized("./...", NULL)); must_fail(ensure_file_path_normalized("dir/sub/..", NULL));
must_fail(ensure_normalized("d1/...", NULL)); must_fail(ensure_file_path_normalized("dir//sub/..",NULL));
must_fail(ensure_normalized("d1/.../", NULL)); must_fail(ensure_file_path_normalized("dir//sub/../", NULL));
must_fail(ensure_normalized("d1/.../d2", 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"));
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));
END_TEST
BEGIN_TEST(dir_path_prettifying)
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_normalized("/./testrepo.git", "/testrepo.git/")); must_pass(ensure_dir_path_normalized("/./testrepo.git", "/testrepo.git/"));
must_pass(ensure_normalized("/./.git", "/.git/")); must_pass(ensure_dir_path_normalized("/./.git", "/.git/"));
must_pass(ensure_normalized("/./git.", "/git./")); must_pass(ensure_dir_path_normalized("/./git.", "/git./"));
must_pass(ensure_normalized("/git./", "/git./")); must_pass(ensure_dir_path_normalized("/git./", "/git./"));
must_pass(ensure_normalized("/", "/")); must_pass(ensure_dir_path_normalized("/", "/"));
must_pass(ensure_normalized("//", "/")); must_pass(ensure_dir_path_normalized("//", "/"));
must_pass(ensure_normalized("///", "/")); must_pass(ensure_dir_path_normalized("///", "/"));
must_pass(ensure_normalized("/.", "/")); must_pass(ensure_dir_path_normalized("/.", "/"));
must_pass(ensure_normalized("/./", "/")); must_pass(ensure_dir_path_normalized("/./", "/"));
must_fail(ensure_normalized("/./..", NULL)); must_fail(ensure_dir_path_normalized("/./..", NULL));
must_fail(ensure_normalized("/../.", NULL)); must_fail(ensure_dir_path_normalized("/../.", NULL));
must_fail(ensure_normalized("/./.././/", NULL)); must_fail(ensure_dir_path_normalized("/./.././/", NULL));
must_pass(ensure_normalized("/dir/..", "/")); must_pass(ensure_dir_path_normalized("/dir/..", "/"));
must_pass(ensure_normalized("/dir/sub/../..", "/")); must_pass(ensure_dir_path_normalized("/dir/sub/../..", "/"));
must_fail(ensure_normalized("/dir/sub/../../..", NULL)); must_fail(ensure_dir_path_normalized("/dir/sub/../../..", NULL));
must_pass(ensure_normalized("/dir", "/dir/")); must_pass(ensure_dir_path_normalized("/dir", "/dir/"));
must_pass(ensure_normalized("/dir//", "/dir/")); must_pass(ensure_dir_path_normalized("/dir//", "/dir/"));
must_pass(ensure_normalized("/./dir", "/dir/")); must_pass(ensure_dir_path_normalized("/./dir", "/dir/"));
must_pass(ensure_normalized("/dir/.", "/dir/")); must_pass(ensure_dir_path_normalized("/dir/.", "/dir/"));
must_pass(ensure_normalized("/dir///./", "/dir/")); must_pass(ensure_dir_path_normalized("/dir///./", "/dir/"));
must_pass(ensure_normalized("/dir//sub/..", "/dir/")); must_pass(ensure_dir_path_normalized("/dir//sub/..", "/dir/"));
must_pass(ensure_normalized("/dir/sub/../", "/dir/")); must_pass(ensure_dir_path_normalized("/dir/sub/../", "/dir/"));
must_pass(ensure_normalized("//dir/sub/../.", "/dir/")); must_pass(ensure_dir_path_normalized("//dir/sub/../.", "/dir/"));
must_pass(ensure_normalized("/dir/s1/../s2/", "/dir/s2/")); must_pass(ensure_dir_path_normalized("/dir/s1/../s2/", "/dir/s2/"));
must_pass(ensure_normalized("/d1/s1///s2/..//../s3/", "/d1/s3/")); must_pass(ensure_dir_path_normalized("/d1/s1///s2/..//../s3/", "/d1/s3/"));
must_pass(ensure_normalized("/d1/s1//../s2/../../d2", "/d2/")); must_pass(ensure_dir_path_normalized("/d1/s1//../s2/../../d2", "/d2/"));
must_fail(ensure_normalized("/....", NULL)); must_fail(ensure_dir_path_normalized("/....", NULL));
must_fail(ensure_normalized("/...", NULL)); must_fail(ensure_dir_path_normalized("/...", NULL));
must_fail(ensure_normalized("/./...", NULL)); must_fail(ensure_dir_path_normalized("/./...", NULL));
must_fail(ensure_normalized("/d1/...", NULL)); must_fail(ensure_dir_path_normalized("/d1/...", NULL));
must_fail(ensure_normalized("/d1/.../", NULL)); must_fail(ensure_dir_path_normalized("/d1/.../", NULL));
must_fail(ensure_normalized("/d1/.../d2", NULL)); must_fail(ensure_dir_path_normalized("/d1/.../d2", NULL));
END_TEST END_TEST
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment