Skip to content

Commit dd748db

Browse files
committed
fs_path: make empty component validation optional
1 parent bef02d3 commit dd748db

File tree

3 files changed

+38
-15
lines changed

3 files changed

+38
-15
lines changed

src/fs_path.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1599,7 +1599,7 @@ static bool validate_component(
15991599
unsigned int flags)
16001600
{
16011601
if (len == 0)
1602-
return false;
1602+
return !(flags & GIT_FS_PATH_REJECT_EMPTY_COMPONENT);
16031603

16041604
if ((flags & GIT_FS_PATH_REJECT_TRAVERSAL) &&
16051605
len == 1 && component[0] == '.')
@@ -1644,6 +1644,9 @@ bool git_fs_path_is_valid_str_ext(
16441644
const char *start, *c;
16451645
size_t len = 0;
16461646

1647+
if (!flags)
1648+
return true;
1649+
16471650
for (start = c = path->ptr; *c && len < path->size; c++, len++) {
16481651
if (!validate_char(*c, flags))
16491652
return false;

src/fs_path.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -591,7 +591,8 @@ extern bool git_fs_path_is_local_file_url(const char *file_url);
591591
extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url_or_path);
592592

593593
/* Flags to determine path validity in `git_fs_path_isvalid` */
594-
#define GIT_FS_PATH_REJECT_TRAVERSAL (1 << 0)
594+
#define GIT_FS_PATH_REJECT_EMPTY_COMPONENT (1 << 0)
595+
#define GIT_FS_PATH_REJECT_TRAVERSAL (1 << 1)
595596
#define GIT_FS_PATH_REJECT_SLASH (1 << 2)
596597
#define GIT_FS_PATH_REJECT_BACKSLASH (1 << 3)
597598
#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
608609
*/
609610
#ifdef GIT_WIN32
610611
# define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \
612+
GIT_FS_PATH_REJECT_EMPTY_COMPONENT | \
611613
GIT_FS_PATH_REJECT_TRAVERSAL | \
612614
GIT_FS_PATH_REJECT_BACKSLASH | \
613615
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
617619
GIT_FS_PATH_REJECT_NT_CHARS
618620
#else
619621
# define GIT_FS_PATH_REJECT_FILESYSTEM_DEFAULTS \
622+
GIT_FS_PATH_REJECT_EMPTY_COMPONENT | \
620623
GIT_FS_PATH_REJECT_TRAVERSAL
621624
#endif
622625

tests/path/core.c

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -68,41 +68,58 @@ void test_path_core__isvalid_standard(void)
6868
void test_path_core__isvalid_standard_str(void)
6969
{
7070
git_str str = GIT_STR_INIT_CONST("foo/bar//zap", 0);
71+
unsigned int flags = GIT_FS_PATH_REJECT_EMPTY_COMPONENT;
7172

7273
str.size = 0;
73-
cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0));
74+
cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags));
7475

7576
str.size = 3;
76-
cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0));
77+
cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags));
7778

7879
str.size = 4;
79-
cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0));
80+
cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags));
8081

8182
str.size = 5;
82-
cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0));
83+
cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags));
8384

8485
str.size = 7;
85-
cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, 0));
86+
cl_assert_equal_b(true, git_fs_path_is_valid_str(&str, flags));
8687

8788
str.size = 8;
88-
cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0));
89+
cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags));
8990

9091
str.size = strlen(str.ptr);
91-
cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, 0));
92+
cl_assert_equal_b(false, git_fs_path_is_valid_str(&str, flags));
9293
}
9394

9495
void test_path_core__isvalid_empty_dir_component(void)
9596
{
96-
cl_assert_equal_b(false, git_fs_path_is_valid("foo//bar", 0));
97+
unsigned int flags = GIT_FS_PATH_REJECT_EMPTY_COMPONENT;
98+
99+
/* empty component */
100+
cl_assert_equal_b(true, git_fs_path_is_valid("foo//bar", 0));
101+
102+
/* leading slash */
103+
cl_assert_equal_b(true, git_fs_path_is_valid("/", 0));
104+
cl_assert_equal_b(true, git_fs_path_is_valid("/foo", 0));
105+
cl_assert_equal_b(true, git_fs_path_is_valid("/foo/bar", 0));
106+
107+
/* trailing slash */
108+
cl_assert_equal_b(true, git_fs_path_is_valid("foo/", 0));
109+
cl_assert_equal_b(true, git_fs_path_is_valid("foo/bar/", 0));
110+
111+
112+
/* empty component */
113+
cl_assert_equal_b(false, git_fs_path_is_valid("foo//bar", flags));
97114

98115
/* leading slash */
99-
cl_assert_equal_b(false, git_fs_path_is_valid("/", 0));
100-
cl_assert_equal_b(false, git_fs_path_is_valid("/foo", 0));
101-
cl_assert_equal_b(false, git_fs_path_is_valid("/foo/bar", 0));
116+
cl_assert_equal_b(false, git_fs_path_is_valid("/", flags));
117+
cl_assert_equal_b(false, git_fs_path_is_valid("/foo", flags));
118+
cl_assert_equal_b(false, git_fs_path_is_valid("/foo/bar", flags));
102119

103120
/* trailing slash */
104-
cl_assert_equal_b(false, git_fs_path_is_valid("foo/", 0));
105-
cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar/", 0));
121+
cl_assert_equal_b(false, git_fs_path_is_valid("foo/", flags));
122+
cl_assert_equal_b(false, git_fs_path_is_valid("foo/bar/", flags));
106123
}
107124

108125
void test_path_core__isvalid_dot_and_dotdot(void)

0 commit comments

Comments
 (0)