c++ - 检查 std::filesystem::path 是否在目录中
问题描述
我有一个由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
。
如何检查生成的文件是否保持在其允许的边界内?
解决方案
首先,您需要标准化最终路径。这将删除路径中的所有.
和..
s。然后,您需要检查它是否在其目录迭代器范围内(相对于root
. 并且有一个标准库算法。
总的来说,代码如下所示:
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;
}
请注意,这仅在理论上有效;用户可能在根目录中使用了符号链接恶作剧来突破您的根目录。您需要使用canonical
而不是lexically_normal
确保不会发生这种情况。但是,canonical
要求该路径存在,因此如果这是需要创建的文件/目录的路径,它将不起作用。
推荐阅读
- laravel - laravel 在 where 子句中有很多多态关系
- sql - 如何计算 SQL 中返回的记录数?
- r - 如何在R中找到一列的最高编号并打印该行的两列?
- python-3.x - 在张量流中,如何计算从多列中具有 NaN 的 csv 生成的批次的每一列的平均值?
- xml - 带有 RSS 的 truepush.com 推送通知图标
- css - CSS 使两个不同比例的图像能够填充容器宽度并具有相同的高度
- java - 如何使用 .flex 文件解决此语法问题?
- javascript - 如何获取标记位置(x,y)AR.js
- javascript - 检索文档数据,其中条件值是子集合值
- c - 使用 WSARecvMsg 时查找多播 UDP 数据包的发送者