Check the input and destination paths before converting a game file onto itself

Before these changes you could tell Dolphin to convert a game file into the same format it is already in, leading to the FileDialog using the input path as the default destination path
An unsuspecting user could then click Save and Dolphin would try to convert the input file by writing the destination file on top of it... leading to an I/O error and the input file being entirely removed
This commit is contained in:
Yann Hodiesne 2023-02-17 11:56:07 +01:00
parent 28331c5905
commit cb42a03299
No known key found for this signature in database
GPG Key ID: 16D15289BA50630E

View File

@ -4,6 +4,7 @@
#include "DolphinQt/ConvertDialog.h" #include "DolphinQt/ConvertDialog.h"
#include <algorithm> #include <algorithm>
#include <filesystem>
#include <functional> #include <functional>
#include <future> #include <future>
#include <memory> #include <memory>
@ -22,6 +23,7 @@
#include "Common/Assert.h" #include "Common/Assert.h"
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "Common/StringUtil.h"
#include "DiscIO/Blob.h" #include "DiscIO/Blob.h"
#include "DiscIO/DiscUtils.h" #include "DiscIO/DiscUtils.h"
#include "DiscIO/ScrubbedBlob.h" #include "DiscIO/ScrubbedBlob.h"
@ -410,6 +412,21 @@ void ConvertDialog::Convert()
} }
} }
if (std::filesystem::exists(StringToPath(dst_path.toStdString())))
{
std::error_code ec;
if (std::filesystem::equivalent(StringToPath(dst_path.toStdString()),
StringToPath(original_path), ec))
{
ModalMessageBox::critical(
this, tr("Error"),
tr("The destination file cannot be the same as the source file\n\n"
"Please select another destination path for \"%1\"")
.arg(QString::fromStdString(original_path)));
continue;
}
}
ParallelProgressDialog progress_dialog(tr("Converting..."), tr("Abort"), 0, 100, this); ParallelProgressDialog progress_dialog(tr("Converting..."), tr("Abort"), 0, 100, this);
progress_dialog.GetRaw()->setWindowModality(Qt::WindowModal); progress_dialog.GetRaw()->setWindowModality(Qt::WindowModal);
progress_dialog.GetRaw()->setWindowTitle(tr("Progress")); progress_dialog.GetRaw()->setWindowTitle(tr("Progress"));