Commit dd748dbe by Edward Thomson

fs_path: make empty component validation optional

parent bef02d3e
...@@ -1599,7 +1599,7 @@ static bool validate_component( ...@@ -1599,7 +1599,7 @@ static bool validate_component(
unsigned int flags) unsigned int flags)
{ {
if (len == 0) if (len == 0)
return false; return !(flags & GIT_FS_PATH_REJECT_EMPTY_COMPONENT);
if ((flags & GIT_FS_PATH_REJECT_TRAVERSAL) && if ((flags & GIT_FS_PATH_REJECT_TRAVERSAL) &&
len == 1 && component[0] == '.') len == 1 && component[0] == '.')
...@@ -1644,6 +1644,9 @@ bool git_fs_path_is_valid_str_ext( ...@@ -1644,6 +1644,9 @@ bool git_fs_path_is_valid_str_ext(
const char *start, *c; const char *start, *c;
size_t len = 0; size_t len = 0;
if (!flags)
return true;
for (start = c = path->ptr; *c && len < path->size; c++, len++) { for (start = c = path->ptr; *c && len < path->size; c++, len++) {
if (!validate_char(*c, flags)) if (!validate_char(*c, flags))
return false; return false;
......
...@@ -591,7 +591,8 @@ extern bool git_fs_path_is_local_file_url(const char *file_url); ...@@ -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); 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` */ /* 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_SLASH (1 << 2)
#define GIT_FS_PATH_REJECT_BACKSLASH (1 << 3) #define GIT_FS_PATH_REJECT_BACKSLASH (1 << 3)
#define GIT_FS_PATH_REJECT_TRAILING_DOT (1 << 4) #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 ...@@ -608,6 +609,7 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url
*/ */
#ifdef GIT_WIN32 #ifdef GIT_WIN32
# define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \ # define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \
GIT_FS_PATH_REJECT_EMPTY_COMPONENT | \
GIT_FS_PATH_REJECT_TRAVERSAL | \ GIT_FS_PATH_REJECT_TRAVERSAL | \
GIT_FS_PATH_REJECT_BACKSLASH | \ GIT_FS_PATH_REJECT_BACKSLASH | \
GIT_FS_PATH_REJECT_TRAILING_DOT | \ 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 ...@@ -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 GIT_FS_PATH_REJECT_NT_CHARS
#else #else
# define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \ # define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \
GIT_FS_PATH_REJECT_EMPTY_COMPONENT | \
GIT_FS_PATH_REJECT_TRAVERSAL GIT_FS_PATH_REJECT_TRAVERSAL
#endif #endif
......
...@@ -68,41 +68,58 @@ void test_path_core__isvalid_standard(void) ...@@ -68,41 +68,58 @@ void test_path_core__isvalid_standard(void)
void test_path_core__isvalid_standard_str(void) void test_path_core__isvalid_standard_str(void)
{ {
git_str str = GIT_STR_INIT_CONST("foo/bar//zap", 0); git_str str = GIT_STR_INIT_CONST("foo/bar//zap", 0);
unsigned int flags = GIT_FS_PATH_REJECT_EMPTY_COMPONENT;
str.size = 0; 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; 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; 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; 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; 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; 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); 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) 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 */ /* leading slash */
cl_assert_equal_b(false, git_fs_path_is_valid("/", 0)); cl_assert_equal_b(false, git_fs_path_is_valid("/", flags));
cl_assert_equal_b(false, git_fs_path_is_valid("/foo", 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", 0)); cl_assert_equal_b(false, git_fs_path_is_valid("/foo/bar", flags));
/* trailing slash */ /* 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/", flags));
cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar/", 0)); cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar/", flags));
} }
void test_path_core__isvalid_dot_and_dotdot(void) void test_path_core__isvalid_dot_and_dotdot(void)
......
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