fs_path: add length with suffix validation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
diff --git a/src/fs_path.c b/src/fs_path.c
index 9079c30..5698014 100644
--- a/src/fs_path.c
+++ b/src/fs_path.c
@@ -1715,6 +1715,29 @@ bool git_fs_path_str_is_valid_ext(
return true;
}
+int git_fs_path_validate_str_length_with_suffix(
+ git_str *path,
+ size_t suffix_len)
+{
+#ifdef GIT_WIN32
+ size_t utf8_len = git_utf8_char_length(path->ptr, path->size);
+ size_t total_len;
+
+ if (GIT_ADD_SIZET_OVERFLOW(&total_len, utf8_len, suffix_len) ||
+ total_len > MAX_PATH) {
+
+ git_error_set(GIT_ERROR_FILESYSTEM, "path too long: '%.*s'",
+ (int)path->size, path->ptr);
+ return -1;
+ }
+#else
+ GIT_UNUSED(path);
+ GIT_UNUSED(suffix_len);
+#endif
+
+ return 0;
+}
+
#ifdef GIT_WIN32
GIT_INLINE(bool) should_validate_longpaths(git_repository *repo)
{
diff --git a/src/fs_path.h b/src/fs_path.h
index 947c4ae..116e8f9 100644
--- a/src/fs_path.h
+++ b/src/fs_path.h
@@ -677,6 +677,10 @@ GIT_INLINE(bool) git_fs_path_str_is_valid(
return git_fs_path_str_is_valid_ext(path, flags, NULL, NULL, NULL, NULL);
}
+extern int git_fs_path_validate_str_length_with_suffix(
+ git_str *path,
+ size_t suffix_len);
+
/**
* Validate an on-disk path, taking into account that it will have a
* suffix appended (eg, `.lock`).
diff --git a/src/refdb_fs.c b/src/refdb_fs.c
index dc291d0..097d2b3 100644
--- a/src/refdb_fs.c
+++ b/src/refdb_fs.c
@@ -77,7 +77,7 @@ GIT_INLINE(int) loose_path(
if (git_str_joinpath(out, base, refname) < 0)
return -1;
- return git_fs_path_validate_filesystem_with_suffix(out->ptr, out->size,
+ return git_fs_path_validate_str_length_with_suffix(out,
CONST_STRLEN(".lock"));
}
diff --git a/src/repository.c b/src/repository.c
index f564453..3b3f7ca 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -240,8 +240,8 @@ GIT_INLINE(int) validate_repo_path(git_str *path)
CONST_STRLEN("objects/pack/pack-.pack.lock") +
GIT_OID_HEXSZ;
- return git_fs_path_validate_filesystem_with_suffix(
- path->ptr, path->size, suffix_len);
+ return git_fs_path_validate_str_length_with_suffix(
+ path, suffix_len);
}
/*