common: fs: Validate paths for path length
This commit is contained in:
@@ -14,8 +14,8 @@ namespace fs = std::filesystem;
|
|||||||
// File Operations
|
// File Operations
|
||||||
|
|
||||||
bool NewFile(const fs::path& path, u64 size) {
|
bool NewFile(const fs::path& path, u64 size) {
|
||||||
if (path.empty()) {
|
if (!ValidatePath(path)) {
|
||||||
LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path));
|
LOG_ERROR(Common_Filesystem, "Input path is not valid, path={}", PathToUTF8String(path));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,8 +52,8 @@ bool NewFile(const fs::path& path, u64 size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RemoveFile(const fs::path& path) {
|
bool RemoveFile(const fs::path& path) {
|
||||||
if (path.empty()) {
|
if (!ValidatePath(path)) {
|
||||||
LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path));
|
LOG_ERROR(Common_Filesystem, "Input path is not valid, path={}", PathToUTF8String(path));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,8 +86,9 @@ bool RemoveFile(const fs::path& path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RenameFile(const fs::path& old_path, const fs::path& new_path) {
|
bool RenameFile(const fs::path& old_path, const fs::path& new_path) {
|
||||||
if (old_path.empty() || new_path.empty()) {
|
if (!ValidatePath(old_path) || !ValidatePath(new_path)) {
|
||||||
LOG_ERROR(Common_Filesystem, "One or both input path(s) is empty, old_path={}, new_path={}",
|
LOG_ERROR(Common_Filesystem,
|
||||||
|
"One or both input path(s) is not valid, old_path={}, new_path={}",
|
||||||
PathToUTF8String(old_path), PathToUTF8String(new_path));
|
PathToUTF8String(old_path), PathToUTF8String(new_path));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -129,8 +130,8 @@ bool RenameFile(const fs::path& old_path, const fs::path& new_path) {
|
|||||||
|
|
||||||
std::shared_ptr<IOFile> FileOpen(const fs::path& path, FileAccessMode mode, FileType type,
|
std::shared_ptr<IOFile> FileOpen(const fs::path& path, FileAccessMode mode, FileType type,
|
||||||
FileShareFlag flag) {
|
FileShareFlag flag) {
|
||||||
if (path.empty()) {
|
if (!ValidatePath(path)) {
|
||||||
LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path));
|
LOG_ERROR(Common_Filesystem, "Input path is not valid, path={}", PathToUTF8String(path));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,8 +163,8 @@ std::shared_ptr<IOFile> FileOpen(const fs::path& path, FileAccessMode mode, File
|
|||||||
// Directory Operations
|
// Directory Operations
|
||||||
|
|
||||||
bool CreateDir(const fs::path& path) {
|
bool CreateDir(const fs::path& path) {
|
||||||
if (path.empty()) {
|
if (!ValidatePath(path)) {
|
||||||
LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path));
|
LOG_ERROR(Common_Filesystem, "Input path is not valid, path={}", PathToUTF8String(path));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,8 +197,8 @@ bool CreateDir(const fs::path& path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CreateDirs(const fs::path& path) {
|
bool CreateDirs(const fs::path& path) {
|
||||||
if (path.empty()) {
|
if (!ValidatePath(path)) {
|
||||||
LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path));
|
LOG_ERROR(Common_Filesystem, "Input path is not valid, path={}", PathToUTF8String(path));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,8 +233,8 @@ bool CreateParentDirs(const fs::path& path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RemoveDir(const fs::path& path) {
|
bool RemoveDir(const fs::path& path) {
|
||||||
if (path.empty()) {
|
if (!ValidatePath(path)) {
|
||||||
LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path));
|
LOG_ERROR(Common_Filesystem, "Input path is not valid, path={}", PathToUTF8String(path));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,8 +267,8 @@ bool RemoveDir(const fs::path& path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RemoveDirRecursively(const fs::path& path) {
|
bool RemoveDirRecursively(const fs::path& path) {
|
||||||
if (path.empty()) {
|
if (!ValidatePath(path)) {
|
||||||
LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path));
|
LOG_ERROR(Common_Filesystem, "Input path is not valid, path={}", PathToUTF8String(path));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -301,8 +302,8 @@ bool RemoveDirRecursively(const fs::path& path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RemoveDirContentsRecursively(const fs::path& path) {
|
bool RemoveDirContentsRecursively(const fs::path& path) {
|
||||||
if (path.empty()) {
|
if (!ValidatePath(path)) {
|
||||||
LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path));
|
LOG_ERROR(Common_Filesystem, "Input path is not valid, path={}", PathToUTF8String(path));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -353,8 +354,9 @@ bool RemoveDirContentsRecursively(const fs::path& path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool RenameDir(const fs::path& old_path, const fs::path& new_path) {
|
bool RenameDir(const fs::path& old_path, const fs::path& new_path) {
|
||||||
if (old_path.empty() || new_path.empty()) {
|
if (!ValidatePath(old_path) || !ValidatePath(new_path)) {
|
||||||
LOG_ERROR(Common_Filesystem, "One or both input path(s) is empty, old_path={}, new_path={}",
|
LOG_ERROR(Common_Filesystem,
|
||||||
|
"One or both input path(s) is not valid, old_path={}, new_path={}",
|
||||||
PathToUTF8String(old_path), PathToUTF8String(new_path));
|
PathToUTF8String(old_path), PathToUTF8String(new_path));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -396,8 +398,8 @@ bool RenameDir(const fs::path& old_path, const fs::path& new_path) {
|
|||||||
|
|
||||||
void IterateDirEntries(const std::filesystem::path& path, const DirEntryCallable& callback,
|
void IterateDirEntries(const std::filesystem::path& path, const DirEntryCallable& callback,
|
||||||
DirEntryFilter filter) {
|
DirEntryFilter filter) {
|
||||||
if (path.empty()) {
|
if (!ValidatePath(path)) {
|
||||||
LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path));
|
LOG_ERROR(Common_Filesystem, "Input path is not valid, path={}", PathToUTF8String(path));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,8 +454,8 @@ void IterateDirEntries(const std::filesystem::path& path, const DirEntryCallable
|
|||||||
|
|
||||||
void IterateDirEntriesRecursively(const std::filesystem::path& path,
|
void IterateDirEntriesRecursively(const std::filesystem::path& path,
|
||||||
const DirEntryCallable& callback, DirEntryFilter filter) {
|
const DirEntryCallable& callback, DirEntryFilter filter) {
|
||||||
if (path.empty()) {
|
if (!ValidatePath(path)) {
|
||||||
LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path));
|
LOG_ERROR(Common_Filesystem, "Input path is not valid, path={}", PathToUTF8String(path));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class IOFile;
|
|||||||
* Creates a new file at path with the specified size.
|
* Creates a new file at path with the specified size.
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - Input path is empty
|
* - Input path is not valid
|
||||||
* - The input path's parent directory does not exist
|
* - The input path's parent directory does not exist
|
||||||
* - Filesystem object at path exists
|
* - Filesystem object at path exists
|
||||||
* - Filesystem at path is read only
|
* - Filesystem at path is read only
|
||||||
@@ -47,7 +47,7 @@ template <typename Path>
|
|||||||
* Removes a file at path.
|
* Removes a file at path.
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - Input path is empty
|
* - Input path is not valid
|
||||||
* - Filesystem object at path is not a file
|
* - Filesystem object at path is not a file
|
||||||
* - Filesystem at path is read only
|
* - Filesystem at path is read only
|
||||||
*
|
*
|
||||||
@@ -72,7 +72,7 @@ template <typename Path>
|
|||||||
* Renames a file from old_path to new_path.
|
* Renames a file from old_path to new_path.
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - One or both input path(s) is empty
|
* - One or both input path(s) is not valid
|
||||||
* - Filesystem object at old_path does not exist
|
* - Filesystem object at old_path does not exist
|
||||||
* - Filesystem object at old_path is not a file
|
* - Filesystem object at old_path is not a file
|
||||||
* - Filesystem object at new_path exists
|
* - Filesystem object at new_path exists
|
||||||
@@ -109,7 +109,7 @@ template <typename Path1, typename Path2>
|
|||||||
* These behaviors are documented in each enum value of FileAccessMode.
|
* These behaviors are documented in each enum value of FileAccessMode.
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - Input path is empty
|
* - Input path is not valid
|
||||||
* - Filesystem object at path is not a file
|
* - Filesystem object at path is not a file
|
||||||
* - The file is not opened
|
* - The file is not opened
|
||||||
*
|
*
|
||||||
@@ -147,7 +147,7 @@ template <typename Path>
|
|||||||
* If you intend to create the parent directory of a file, use CreateParentDir instead.
|
* If you intend to create the parent directory of a file, use CreateParentDir instead.
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - Input path is empty
|
* - Input path is not valid
|
||||||
* - The input path's parent directory does not exist
|
* - The input path's parent directory does not exist
|
||||||
* - Filesystem at path is read only
|
* - Filesystem at path is read only
|
||||||
*
|
*
|
||||||
@@ -176,7 +176,7 @@ template <typename Path>
|
|||||||
* Unlike CreateDir, this creates all of input path's parent directories if they do not exist.
|
* Unlike CreateDir, this creates all of input path's parent directories if they do not exist.
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - Input path is empty
|
* - Input path is not valid
|
||||||
* - Filesystem at path is read only
|
* - Filesystem at path is read only
|
||||||
*
|
*
|
||||||
* @param path Filesystem path
|
* @param path Filesystem path
|
||||||
@@ -242,7 +242,7 @@ template <typename Path>
|
|||||||
* Removes a directory at path.
|
* Removes a directory at path.
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - Input path is empty
|
* - Input path is not valid
|
||||||
* - Filesystem object at path is not a directory
|
* - Filesystem object at path is not a directory
|
||||||
* - The given directory is not empty
|
* - The given directory is not empty
|
||||||
* - Filesystem at path is read only
|
* - Filesystem at path is read only
|
||||||
@@ -268,7 +268,7 @@ template <typename Path>
|
|||||||
* Removes all the contents within the given directory and removes the directory itself.
|
* Removes all the contents within the given directory and removes the directory itself.
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - Input path is empty
|
* - Input path is not valid
|
||||||
* - Filesystem object at path is not a directory
|
* - Filesystem object at path is not a directory
|
||||||
* - Filesystem at path is read only
|
* - Filesystem at path is read only
|
||||||
*
|
*
|
||||||
@@ -293,7 +293,7 @@ template <typename Path>
|
|||||||
* Removes all the contents within the given directory without removing the directory itself.
|
* Removes all the contents within the given directory without removing the directory itself.
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - Input path is empty
|
* - Input path is not valid
|
||||||
* - Filesystem object at path is not a directory
|
* - Filesystem object at path is not a directory
|
||||||
* - Filesystem at path is read only
|
* - Filesystem at path is read only
|
||||||
*
|
*
|
||||||
@@ -318,7 +318,7 @@ template <typename Path>
|
|||||||
* Renames a directory from old_path to new_path.
|
* Renames a directory from old_path to new_path.
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - One or both input path(s) is empty
|
* - One or both input path(s) is not valid
|
||||||
* - Filesystem object at old_path does not exist
|
* - Filesystem object at old_path does not exist
|
||||||
* - Filesystem object at old_path is not a directory
|
* - Filesystem object at old_path is not a directory
|
||||||
* - Filesystem object at new_path exists
|
* - Filesystem object at new_path exists
|
||||||
@@ -358,7 +358,7 @@ template <typename Path1, typename Path2>
|
|||||||
* If the callback returns false or there is an error, the iteration is immediately halted.
|
* If the callback returns false or there is an error, the iteration is immediately halted.
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - Input path is empty
|
* - Input path is not valid
|
||||||
* - Filesystem object at path is not a directory
|
* - Filesystem object at path is not a directory
|
||||||
*
|
*
|
||||||
* @param path Filesystem path
|
* @param path Filesystem path
|
||||||
@@ -388,7 +388,7 @@ void IterateDirEntries(const Path& path, const DirEntryCallable& callback,
|
|||||||
* If the callback returns false or there is an error, the iteration is immediately halted.
|
* If the callback returns false or there is an error, the iteration is immediately halted.
|
||||||
*
|
*
|
||||||
* Failures occur when:
|
* Failures occur when:
|
||||||
* - Input path is empty
|
* - Input path is not valid
|
||||||
* - Filesystem object at path does not exist
|
* - Filesystem object at path does not exist
|
||||||
* - Filesystem object at path is not a directory
|
* - Filesystem object at path is not a directory
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -4,10 +4,6 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef MAX_PATH
|
|
||||||
#define MAX_PATH 260
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// yuzu data directories
|
// yuzu data directories
|
||||||
|
|
||||||
#define YUZU_DIR "yuzu"
|
#define YUZU_DIR "yuzu"
|
||||||
|
|||||||
@@ -37,6 +37,16 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef MAX_PATH
|
||||||
|
#ifdef _WIN32
|
||||||
|
// This is the maximum number of UTF-16 code units permissible in Windows file paths
|
||||||
|
#define MAX_PATH 260
|
||||||
|
#else
|
||||||
|
// This is the maximum number of UTF-8 code units permissible in all other OSes' file paths
|
||||||
|
#define MAX_PATH 1024
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Common::FS {
|
namespace Common::FS {
|
||||||
|
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
@@ -125,6 +135,27 @@ std::string PathToUTF8String(const fs::path& path) {
|
|||||||
return std::string{utf8_string.begin(), utf8_string.end()};
|
return std::string{utf8_string.begin(), utf8_string.end()};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ValidatePath(const fs::path& path) {
|
||||||
|
if (path.empty()) {
|
||||||
|
LOG_ERROR(Common_Filesystem, "Input path is empty, path={}", PathToUTF8String(path));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (path.u16string().size() >= MAX_PATH) {
|
||||||
|
LOG_ERROR(Common_Filesystem, "Input path is too long, path={}", PathToUTF8String(path));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (path.u8string().size() >= MAX_PATH) {
|
||||||
|
LOG_ERROR(Common_Filesystem, "Input path is too long, path={}", PathToUTF8String(path));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
fs::path ConcatPath(const fs::path& first, const fs::path& second) {
|
fs::path ConcatPath(const fs::path& first, const fs::path& second) {
|
||||||
const bool second_has_dir_sep = IsDirSeparator(second.u8string().front());
|
const bool second_has_dir_sep = IsDirSeparator(second.u8string().front());
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,30 @@ enum class YuzuPath {
|
|||||||
*/
|
*/
|
||||||
[[nodiscard]] std::string PathToUTF8String(const std::filesystem::path& path);
|
[[nodiscard]] std::string PathToUTF8String(const std::filesystem::path& path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Validates a given path.
|
||||||
|
*
|
||||||
|
* A given path is valid if it meets these conditions:
|
||||||
|
* - The path is not empty
|
||||||
|
* - The path is not too long
|
||||||
|
*
|
||||||
|
* @param path Filesystem path
|
||||||
|
*
|
||||||
|
* @returns True if the path is valid, false otherwise.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] bool ValidatePath(const std::filesystem::path& path);
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
template <typename Path>
|
||||||
|
[[nodiscard]] bool ValidatePath(const Path& path) {
|
||||||
|
if constexpr (IsChar<typename Path::value_type>) {
|
||||||
|
return ValidatePath(ToU8String(path));
|
||||||
|
} else {
|
||||||
|
return ValidatePath(std::filesystem::path{path});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Concatenates two filesystem paths together.
|
* Concatenates two filesystem paths together.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user