diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2021-11-01 13:04:40 -0400 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2021-11-09 15:17:17 +0000 |
commit | dd748dbede1a36f1e929461ecbfcde749eb685bb (patch) | |
tree | 60e695e05378a21db5218c81285a5c0e3b5de395 | |
parent | bef02d3e638ce8c95c9e63622b46d87a0f8ee2b2 (diff) | |
download | libgit2-dd748dbede1a36f1e929461ecbfcde749eb685bb.tar.gz |
fs_path: make empty component validation optional
-rw-r--r-- | src/fs_path.c | 5 | ||||
-rw-r--r-- | src/fs_path.h | 5 | ||||
-rw-r--r-- | tests/path/core.c | 43 |
3 files changed, 38 insertions, 15 deletions
diff --git a/src/fs_path.c b/src/fs_path.c index fa27a6e73..483b21c1e 100644 --- a/src/fs_path.c +++ b/src/fs_path.c @@ -1599,7 +1599,7 @@ static bool validate_component( unsigned int flags) { if (len == 0) - return false; + return !(flags & GIT_FS_PATH_REJECT_EMPTY_COMPONENT); if ((flags & GIT_FS_PATH_REJECT_TRAVERSAL) && len == 1 && component[0] == '.') @@ -1644,6 +1644,9 @@ bool git_fs_path_is_valid_str_ext( const char *start, *c; size_t len = 0; + if (!flags) + return true; + for (start = c = path->ptr; *c && len < path->size; c++, len++) { if (!validate_char(*c, flags)) return false; diff --git a/src/fs_path.h b/src/fs_path.h index 2f4bc9f79..275b3d857 100644 --- a/src/fs_path.h +++ b/src/fs_path.h @@ -591,7 +591,8 @@ extern bool git_fs_path_is_local_file_url(const char *file_url); extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url_or_path); /* Flags to determine path validity in `git_fs_path_isvalid` */ -#define GIT_FS_PATH_REJECT_TRAVERSAL (1 << 0) +#define GIT_FS_PATH_REJECT_EMPTY_COMPONENT (1 << 0) +#define GIT_FS_PATH_REJECT_TRAVERSAL (1 << 1) #define GIT_FS_PATH_REJECT_SLASH (1 << 2) #define GIT_FS_PATH_REJECT_BACKSLASH (1 << 3) #define GIT_FS_PATH_REJECT_TRAILING_DOT (1 << 4) @@ -608,6 +609,7 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url */ #ifdef GIT_WIN32 # define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \ + GIT_FS_PATH_REJECT_EMPTY_COMPONENT | \ GIT_FS_PATH_REJECT_TRAVERSAL | \ GIT_FS_PATH_REJECT_BACKSLASH | \ GIT_FS_PATH_REJECT_TRAILING_DOT | \ @@ -617,6 +619,7 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url GIT_FS_PATH_REJECT_NT_CHARS #else # define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \ + GIT_FS_PATH_REJECT_EMPTY_COMPONENT | \ GIT_FS_PATH_REJECT_TRAVERSAL #endif diff --git a/tests/path/core.c b/tests/path/core.c index 6fa0450ca..ccb328b10 100644 --- a/tests/path/core.c +++ b/tests/path/core.c @@ -68,41 +68,58 @@ void test_path_core__isvalid_standard(void) void test_path_core__isvalid_standard_str(void) { git_str str = GIT_STR_INIT_CONST("foo/bar//zap", 0); + unsigned int flags = GIT_FS_PATH_REJECT_EMPTY_COMPONENT; str.size = 0; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); str.size = 3; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); str.size = 4; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); str.size = 5; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); str.size = 7; - cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags)); str.size = 8; - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); str.size = strlen(str.ptr); - cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0)); + cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags)); } void test_path_core__isvalid_empty_dir_component(void) { - cl_assert_equal_b(false, git_fs_path_is_valid("foo//bar", 0)); + unsigned int flags = GIT_FS_PATH_REJECT_EMPTY_COMPONENT; + + /* empty component */ + cl_assert_equal_b(true, git_fs_path_is_valid("foo//bar", 0)); + + /* leading slash */ + cl_assert_equal_b(true, git_fs_path_is_valid("/", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("/foo", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("/foo/bar", 0)); + + /* trailing slash */ + cl_assert_equal_b(true, git_fs_path_is_valid("foo/", 0)); + cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar/", 0)); + + + /* empty component */ + cl_assert_equal_b(false, git_fs_path_is_valid("foo//bar", flags)); /* leading slash */ - cl_assert_equal_b(false, git_fs_path_is_valid("/", 0)); - cl_assert_equal_b(false, git_fs_path_is_valid("/foo", 0)); - cl_assert_equal_b(false, git_fs_path_is_valid("/foo/bar", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("/", flags)); + cl_assert_equal_b(false, git_fs_path_is_valid("/foo", flags)); + cl_assert_equal_b(false, git_fs_path_is_valid("/foo/bar", flags)); /* trailing slash */ - cl_assert_equal_b(false, git_fs_path_is_valid("foo/", 0)); - cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar/", 0)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/", flags)); + cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar/", flags)); } void test_path_core__isvalid_dot_and_dotdot(void) |