我正在尝试在系统temp文件夹中创建一个唯一的临时目录,并且一直在阅读有关tmpnam()的安全性和文件创建问题的信息。
我写了下面的代码,想知道它是否可以满足这些问题,我对tmpnam()函数的使用是否正确以及是否抛出了filesystem_error?我是否应该添加其他检查(例如temp_directory_path,它也会引发异常)?
// Unique temporary directory path in the system temporary directory path.
std::filesystem::path tmp_dir_path {std::filesystem::temp_directory_path() /= std::tmpnam(nullptr)};
// Attempt to create the directory.
if (std::filesystem::create_directories(tmp_dir_path)) {
// Directory successfully created.
return tmp_dir_path;
} else {
// Directory could not be created.
throw std::filesystem_error("directory could not be created.");
}
答案 0 :(得分:5)
尽管很难猜出std :: tmpnam生成的名称,但是在std :: tmpnam返回到程序尝试使用返回的名称之间,可能有另一个进程创建了具有该名称的文件。创建文件。
问题不在于您如何使用它,而在于您使用它的事实。
例如,在您的代码示例中,如果恶意用户成功猜测并在第一行和第二行之间创建了目录,则它可能会拒绝您应用程序中的服务(DOS),这可能很重要,或者不是很重要。 / p>
相反,有一种方法可以在不兼容POSIX的系统上进行比赛:
答案 1 :(得分:1)
您的代码很好。由于您尝试创建目录,因此OS
将在您的进程与尝试创建同一文件的另一个进程之间进行仲裁,因此,如果您获胜,您将拥有,如果您丢失,则会得到该文件错误。
我最近写了一个类似的函数。是否引发异常取决于您要如何使用此函数。例如,您可以简单地返回打开或关闭的std::fstream
并使用std::fstream::is_open
作为成功的度量标准,或者在失败时返回空的路径名。
如果您不提供std::error_code
参数,则查找std::filesystem::create_directories时会抛出自己的异常,因此您无需抛出自己的异常:
std::filesystem::path tmp_dir_path {std::filesystem::temp_directory_path() /= std::tmpnam(nullptr)};
// Attempt to create the directory.
std::filesystem::create_directories(tmp_dir_path));
// If that failed an exception will have been thrown
// so no need to check or throw your own
// Directory successfully created.
return tmp_dir_path;