From 345f5757e56e28a3a25465dcd84b8ddc674315b9 Mon Sep 17 00:00:00 2001 From: ACB Date: Sun, 12 Feb 2023 14:05:48 +0100 Subject: [PATCH] Create a safe temporary file with is_backup_save_enabled --- drivers/unix/file_access_unix.cpp | 7 ++++++- drivers/windows/file_access_windows.cpp | 14 ++++++++++---- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index 43d3f53904b..59599899501 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -100,6 +100,11 @@ Error FileAccessUnix::open_internal(const String &p_path, int p_mode_flags) { if (is_backup_save_enabled() && (p_mode_flags == WRITE)) { save_path = path; + // Create a temporary file in the same directory as the target file. + path = path + "-XXXXXX"; + if (!mkstemp(path.utf8().ptrw())) { + return ERR_FILE_CANT_OPEN; + } path = path + ".tmp"; } @@ -143,7 +148,7 @@ void FileAccessUnix::_close() { } if (!save_path.is_empty()) { - int rename_error = rename((save_path + ".tmp").utf8().get_data(), save_path.utf8().get_data()); + int rename_error = rename(path.utf8().get_data(), save_path.utf8().get_data()); if (rename_error && close_fail_notify) { close_fail_notify(save_path); diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index ea40622afc5..174d9dd842a 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -130,10 +130,16 @@ Error FileAccessWindows::open_internal(const String &p_path, int p_mode_flags) { if (is_backup_save_enabled() && p_mode_flags == WRITE) { save_path = path; - path = path + ".tmp"; + // Create a temporary file in the same directory as the target file. + WCHAR tmpFileName[MAX_PATH]; + if (GetTempFileNameW((LPCWSTR)(path.get_base_dir().utf16().get_data()), (LPCWSTR)(path.get_file().utf16().get_data()), 0, tmpFileName) == 0) { + last_error = ERR_FILE_CANT_OPEN; + return last_error; + } + path = tmpFileName; } - f = _wfsopen((LPCWSTR)(path.utf16().get_data()), mode_string, _SH_DENYNO); + f = _wfsopen((LPCWSTR)(path.utf16().get_data()), mode_string, is_backup_save_enabled() ? _SH_SECURE : _SH_DENYNO); if (f == nullptr) { switch (errno) { @@ -178,10 +184,10 @@ void FileAccessWindows::_close() { if (!PathFileExistsW((LPCWSTR)(save_path.utf16().get_data()))) { #endif // Creating new file - rename_error = _wrename((LPCWSTR)((save_path + ".tmp").utf16().get_data()), (LPCWSTR)(save_path.utf16().get_data())) != 0; + rename_error = _wrename((LPCWSTR)(path.utf16().get_data()), (LPCWSTR)(save_path.utf16().get_data())) != 0; } else { // Atomic replace for existing file - rename_error = !ReplaceFileW((LPCWSTR)(save_path.utf16().get_data()), (LPCWSTR)((save_path + ".tmp").utf16().get_data()), nullptr, 2 | 4, nullptr, nullptr); + rename_error = !ReplaceFileW((LPCWSTR)(save_path.utf16().get_data()), (LPCWSTR)(path.utf16().get_data()), nullptr, 2 | 4, nullptr, nullptr); } if (rename_error) { attempts--;