создать уникальный временный каталог - PullRequest
0 голосов
/ 21 октября 2018

Я пытаюсь создать уникальный временный каталог в системной временной папке и читал о проблемах безопасности и создания файлов в 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.");

}

Ответы [ 2 ]

0 голосов
/ 21 октября 2018

Ваш код в порядке.Поскольку вы пытаетесь создать каталог, OS будет выполнять арбитраж между вашим процессом и другим процессом, пытающимся создать тот же файл, поэтому, если вы выиграете, вы владеете файлом, а в случае проигрыша вы получите ошибку.

Недавно я написал похожую функцию.Вы выбрасываете исключение или нет, зависит от того, как вы хотите использовать эту функцию.Вы можете, например, просто вернуть открытый или закрытый std::fstream и использовать std::fstream::is_open в качестве меры успеха или вернуть пустой путь при ошибке.

Поиск std :: filesystem ::create_directories вызовет свое собственное исключение, если вы не укажете параметр std::error_code, поэтому вам не нужно выдавать собственное исключение:

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;
0 голосов
/ 21 октября 2018

С cppreference.com :

Хотя имена, сгенерированные std :: tmpnam, трудно угадать, возможно, что файл с таким именем создан другимпроцесс между моментом, когда возвращается std :: tmpnam, и моментом, когда эта программа пытается использовать возвращенное имя для создания файла.

Проблема не в том, как вы его используете, а в том, что вы делаете.

Например, в вашем примере кода, если злонамеренный пользователь успешно угадывает и создает каталог прямо между первой и второй строкой, он может запретить службу (DOS) из вашего приложения, что может быть критическим,или нет.

Вместо этого есть способ сделать это без гонок в POSIX-совместимых системах:

  • Для файлов см. mkstemp (3) для получения дополнительной информации.информация
  • Сведения о каталогах см. mkdtemp (3) для получения дополнительной информации.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...