检查 std::filesystem::path 是否在目录中
Check if an std::filesystem::path is inside a directory
我有一个 std::filesystem::path
表示的根路径。我想将一些用户提供的文件名添加到此路径,并确保生成的路径不在根目录之外。
例如:
std::filesystem::path root = "/foo/bar";
std::filesystem::path userFile = "ham/spam";
std::filesystem::path finalPath = root / userFile;
最后的路径没问题,在/foo/bar
里面。
但是,如果我将 ../ham/spam
赋给 userFile
变量,这将导致文件超出定义 rootPath
.
如何检查生成的文件是否在其允许的范围内?
首先,您需要 normalize the final path. This removes all .
and ..
s in the path. Then, you need to check to see if it has any mismatches in its directory iterator range, relative to root
. And there's a standard library algorithm 为此。
总的来说,代码如下所示:
std::optional<fs::path> MakeAbsolute(const fs::path &root, const fs::path &userPath)
{
auto finalPath = (root / userPath).lexically_normal();
auto[rootEnd, nothing] = std::mismatch(root.begin(), root.end(), finalPath.begin());
if(rootEnd != root.end())
return std::nullopt;
return finalPath;
}
请注意,这仅在理论上有效;用户可能在根目录中使用了符号链接恶作剧来突破您的根目录。您需要 use canonical
而不是 lexically_normal
以确保不会发生这种情况。但是,canonical
要求 存在该路径,因此如果这是指向需要创建的 file/directory 的路径,它将不起作用。
我有一个 std::filesystem::path
表示的根路径。我想将一些用户提供的文件名添加到此路径,并确保生成的路径不在根目录之外。
例如:
std::filesystem::path root = "/foo/bar";
std::filesystem::path userFile = "ham/spam";
std::filesystem::path finalPath = root / userFile;
最后的路径没问题,在/foo/bar
里面。
但是,如果我将 ../ham/spam
赋给 userFile
变量,这将导致文件超出定义 rootPath
.
如何检查生成的文件是否在其允许的范围内?
首先,您需要 normalize the final path. This removes all .
and ..
s in the path. Then, you need to check to see if it has any mismatches in its directory iterator range, relative to root
. And there's a standard library algorithm 为此。
总的来说,代码如下所示:
std::optional<fs::path> MakeAbsolute(const fs::path &root, const fs::path &userPath)
{
auto finalPath = (root / userPath).lexically_normal();
auto[rootEnd, nothing] = std::mismatch(root.begin(), root.end(), finalPath.begin());
if(rootEnd != root.end())
return std::nullopt;
return finalPath;
}
请注意,这仅在理论上有效;用户可能在根目录中使用了符号链接恶作剧来突破您的根目录。您需要 use canonical
而不是 lexically_normal
以确保不会发生这种情况。但是,canonical
要求 存在该路径,因此如果这是指向需要创建的 file/directory 的路径,它将不起作用。