检查 std::filesystem::path 是不是在目录中

Posted

技术标签:

【中文标题】检查 std::filesystem::path 是不是在目录中【英文标题】:Check if an std::filesystem::path is inside a directory检查 std::filesystem::path 是否在目录中 【发布时间】:2020-04-09 14:34:47 【问题描述】:

我有一个由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 之外的文件。

如何检查生成的文件是否保持在其允许的范围内?

【问题讨论】:

这有帮助吗? en.cppreference.com/w/cpp/experimental/fs/canonical 如果std::filesystem 库包含一些计算新absolute 路径的函数,那岂不是很有用? @SamVarshavchik:不,它不会,因为absolute(以及canonical)都需要存在的路径。它可能不会。 【参考方案1】:

首先,您需要normalize the final path。这将删除路径中的所有 ...s。然后,您需要检查它在其目录迭代器范围内是否有任何不匹配,相对于root。还有一个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 要求该路径存在,因此如果这是需要创建的文件/目录的路径,它将不起作用。

【讨论】:

以上是关于检查 std::filesystem::path 是不是在目录中的主要内容,如果未能解决你的问题,请参考以下文章

std::filesystem current_path 返回根目录

php 菜单检查子菜单菜单检查子项菜单检查子项菜单检查子项

产检abap是检查啥

Web书写Test Case时需要考虑的检查点

使用 jQuery 检查收音机时,检查收音机是不是已检查不起作用

ARCGIS如何检查重叠面呢?