c++ - 检查 std::filesystem::path 是否在目录中

标签 c++ c++17 std-filesystem

我有一个由 std::filesystem::path 表示的根路径.我想向该路径添加一些用户提供的文件名,并确保生成的路径不在根目录之外。

例如:

    std::filesystem::path root = "/foo/bar";
    std::filesystem::path userFile = "ham/spam";
    std::filesystem::path finalPath = root / userFile;

最终路径没问题,在/foo/bar里面.
但是如果我给 ../ham/spamuserFile变量,这将导致定义之外的文件 rootPath .

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

最佳答案

首先,您需要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;
}

请注意,这仅在理论上有效;用户可能在根目录中使用了符号链接(symbolic link)恶作剧来突破您的根目录。您需要 use canonical 而不是 lexically_normal以确保不会发生这种情况。但是,canonical要求路径存在,所以如果这是需要创建的文件/目录的路径,它将不起作用。

关于c++ - 检查 std::filesystem::path 是否在目录中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61123627/

相关文章:

c++ - For循环只是......没有开始?

c++ - 编译器可以优化可变长度循环吗?

c++ - 在 Qt 中如何在 QLineEdit 中使用 QFileDialog 添加文件

visual-studio-2017 - VS2017 : E0135 namespace "std" has no member "filesystem"

c# - native NuGet 包安装失败

c++ - SFINAE 检查 operator[] 比我还糊涂?

c++ - 根据模板参数添加成员函数和成员变量

c++ - 使用模板处理string和wstring

c++ - std::在 C++/17 中没有成员 "filesystem"