summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2021-11-01 13:58:18 -0400
committerEdward Thomson <ethomson@edwardthomson.com>2021-11-09 15:17:18 +0000
commitebacd24c6039c992ef9122a0d6f7de0ca4ba3bd1 (patch)
treeb3e8e91bc2d0fa0a61ba88d57c7ff783eeb5ab25
parentdd748dbede1a36f1e929461ecbfcde749eb685bb (diff)
downloadlibgit2-ebacd24c6039c992ef9122a0d6f7de0ca4ba3bd1.tar.gz
fs_path: add long path validation on windows
-rw-r--r--src/fs_path.c29
-rw-r--r--src/fs_path.h10
-rw-r--r--src/path.c2
3 files changed, 37 insertions, 4 deletions
diff --git a/src/fs_path.c b/src/fs_path.c
index 483b21c1e..de3b03957 100644
--- a/src/fs_path.c
+++ b/src/fs_path.c
@@ -1634,11 +1634,25 @@ static bool validate_component(
return true;
}
+#ifdef GIT_WIN32
+GIT_INLINE(bool) validate_length(
+ const char *path,
+ size_t len,
+ size_t utf8_char_len)
+{
+ GIT_UNUSED(path);
+ GIT_UNUSED(len);
+
+ return (utf8_char_len <= MAX_PATH);
+}
+#endif
+
bool git_fs_path_is_valid_str_ext(
const git_str *path,
unsigned int flags,
bool (*validate_char_cb)(char ch, void *payload),
bool (*validate_component_cb)(const char *component, size_t len, void *payload),
+ bool (*validate_length_cb)(const char *path, size_t len, size_t utf8_char_len),
void *payload)
{
const char *start, *c;
@@ -1683,6 +1697,21 @@ bool git_fs_path_is_valid_str_ext(
!validate_component_cb(start, (c - start), payload))
return false;
+#ifdef GIT_WIN32
+ if ((flags & GIT_FS_PATH_REJECT_LONG_PATHS) != 0) {
+ size_t utf8_len = git_utf8_char_length(path->ptr, len);
+
+ if (!validate_length(path->ptr, len, utf8_len))
+ return false;
+
+ if (validate_length_cb &&
+ !validate_length_cb(path->ptr, len, utf8_len))
+ return false;
+ }
+#else
+ GIT_UNUSED(validate_length_cb);
+#endif
+
return true;
}
diff --git a/src/fs_path.h b/src/fs_path.h
index 275b3d857..40b4342f1 100644
--- a/src/fs_path.h
+++ b/src/fs_path.h
@@ -600,8 +600,9 @@ extern int git_fs_path_from_url_or_path(git_str *local_path_out, const char *url
#define GIT_FS_PATH_REJECT_TRAILING_COLON (1 << 6)
#define GIT_FS_PATH_REJECT_DOS_PATHS (1 << 7)
#define GIT_FS_PATH_REJECT_NT_CHARS (1 << 8)
+#define GIT_FS_PATH_REJECT_LONG_PATHS (1 << 9)
-#define GIT_FS_PATH_REJECT_MAX (1 << 8)
+#define GIT_FS_PATH_REJECT_MAX (1 << 9)
/* Default path safety for writing files to disk: since we use the
* Win32 "File Namespace" APIs ("\\?\") we need to protect from
@@ -632,6 +633,7 @@ extern bool git_fs_path_is_valid_str_ext(
unsigned int flags,
bool (*validate_char_cb)(char ch, void *payload),
bool (*validate_component_cb)(const char *component, size_t len, void *payload),
+ bool (*validate_length_cb)(const char *component, size_t len, size_t utf8_char_len),
void *payload);
GIT_INLINE(bool) git_fs_path_is_valid_ext(
@@ -639,6 +641,7 @@ GIT_INLINE(bool) git_fs_path_is_valid_ext(
unsigned int flags,
bool (*validate_char_cb)(char ch, void *payload),
bool (*validate_component_cb)(const char *component, size_t len, void *payload),
+ bool (*validate_length_cb)(const char *component, size_t len, size_t utf8_char_len),
void *payload)
{
const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX);
@@ -647,6 +650,7 @@ GIT_INLINE(bool) git_fs_path_is_valid_ext(
flags,
validate_char_cb,
validate_component_cb,
+ validate_length_cb,
payload);
}
@@ -662,7 +666,7 @@ GIT_INLINE(bool) git_fs_path_is_valid(
unsigned int flags)
{
const git_str str = GIT_STR_INIT_CONST(path, SIZE_MAX);
- return git_fs_path_is_valid_str_ext(&str, flags, NULL, NULL, NULL);
+ return git_fs_path_is_valid_str_ext(&str, flags, NULL, NULL, NULL, NULL);
}
/** Validate a filesystem path in a `git_str`. */
@@ -670,7 +674,7 @@ GIT_INLINE(bool) git_fs_path_is_valid_str(
const git_str *path,
unsigned int flags)
{
- return git_fs_path_is_valid_str_ext(path, flags, NULL, NULL, NULL);
+ return git_fs_path_is_valid_str_ext(path, flags, NULL, NULL, NULL, NULL);
}
/**
diff --git a/src/path.c b/src/path.c
index d54bc5bfe..a6b396f6d 100644
--- a/src/path.c
+++ b/src/path.c
@@ -301,7 +301,7 @@ bool git_path_is_valid(
data.file_mode = file_mode;
data.flags = flags;
- return git_fs_path_is_valid_ext(path, flags, NULL, validate_repo_component, &data);
+ return git_fs_path_is_valid_ext(path, flags, NULL, validate_repo_component, NULL, &data);
}
static const struct {