From f2ab9839e5ef5555363bb36f96a2a027d89bc4eb Mon Sep 17 00:00:00 2001 From: itsmattkc Date: Mon, 15 Jun 2020 13:40:03 +1000 Subject: [PATCH] project: save to temp folder first and then overwrite actual file With this commit, we save to a temporary file first and then cat the end run a copy to overwrite the source file. If the save somehow fails or the program crashes mid-save, this will prevent the user's project file from getting corrupted. --- app/task/project/save/save.cpp | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/app/task/project/save/save.cpp b/app/task/project/save/save.cpp index db026b032..211a70c2a 100644 --- a/app/task/project/save/save.cpp +++ b/app/task/project/save/save.cpp @@ -20,9 +20,12 @@ #include "save.h" +#include #include #include +#include "common/filefunctions.h" + OLIVE_NAMESPACE_ENTER ProjectSaveTask::ProjectSaveTask(ProjectPtr project) : @@ -33,7 +36,10 @@ ProjectSaveTask::ProjectSaveTask(ProjectPtr project) : bool ProjectSaveTask::Run() { - QFile project_file(project_->filename()); + // File to temporarily save to (ensures we can't half-write the user's main file and crash) + QString temp_save = QDir(FileFunctions::GetTempFilePath()).filePath(QStringLiteral("tempsv")); + + QFile project_file(temp_save); if (project_file.open(QFile::WriteOnly | QFile::Text)) { QXmlStreamWriter writer(&project_file); @@ -53,7 +59,20 @@ bool ProjectSaveTask::Run() project_file.close(); - return true; + if (writer.hasError()) { + SetError(tr("Failed to write XML data")); + return false; + } + + // Save was successful, we can now rewrite the original file + QFile original(project_->filename()); + if ((!original.exists() || original.remove()) + && QFile::copy(temp_save, project_->filename())) { + return true; + } else { + SetError(tr("Failed to write to \"%1\".").arg(project_->filename())); + return false; + } } else { SetError(tr("Failed to open file \"%1\" for writing.").arg(project_->filename())); return false;