Commit 622514095fd1d731d35b0d69608911445ba3b0c4

Edward Thomson 2021-11-01T21:09:17

fs_path: add length with suffix validation

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);
 }
 
 /*