Commit ebacd24c by Edward Thomson

fs_path: add long path validation on windows

parent dd748dbe
......@@ -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;
}
......
......@@ -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);
}
/**
......
......@@ -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 {
......
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