Qt: Fix use-after-free in settings reopen()

This commit is contained in:
Stenzek 2024-07-01 18:53:02 +10:00 committed by Connor McLaughlin
parent 3f952c88a4
commit e7139ab801
2 changed files with 13 additions and 9 deletions

View File

@ -303,7 +303,7 @@ void SettingsWindow::onCopyGlobalSettingsClicked()
saveAndReloadGameSettings(); saveAndReloadGameSettings();
QMessageBox::information(reopen(), tr("PCSX2 Settings"), tr("Per-game configuration copied from global settings.")); reopen(tr("Per-game configuration copied from global settings."));
} }
void SettingsWindow::onClearSettingsClicked() void SettingsWindow::onClearSettingsClicked()
@ -324,17 +324,16 @@ void SettingsWindow::onClearSettingsClicked()
Pcsx2Config::ClearConfiguration(m_sif.get()); Pcsx2Config::ClearConfiguration(m_sif.get());
saveAndReloadGameSettings(); saveAndReloadGameSettings();
QMessageBox::information(reopen(), tr("PCSX2 Settings"), tr("Per-game configuration cleared.")); reopen(tr("Per-game configuration cleared."));
} }
SettingsWindow* SettingsWindow::reopen() void SettingsWindow::reopen(const QString& message)
{ {
// This doesn't work for global settings, because MainWindow maintains a pointer. // This doesn't work for global settings, because MainWindow maintains a pointer.
if (!m_sif) if (!m_sif)
return this; return;
close();
// After closing, this pointer is freed. So we need to grab everything early.
std::unique_ptr<INISettingsInterface> new_sif = std::make_unique<INISettingsInterface>(m_sif->GetFileName()); std::unique_ptr<INISettingsInterface> new_sif = std::make_unique<INISettingsInterface>(m_sif->GetFileName());
if (FileSystem::FileExists(new_sif->GetFileName().c_str())) if (FileSystem::FileExists(new_sif->GetFileName().c_str()))
new_sif->Load(); new_sif->Load();
@ -344,9 +343,14 @@ SettingsWindow* SettingsWindow::reopen()
SettingsWindow* dlg = new SettingsWindow(std::move(new_sif), game, m_serial, m_disc_crc, m_filename); SettingsWindow* dlg = new SettingsWindow(std::move(new_sif), game, m_serial, m_disc_crc, m_filename);
dlg->QWidget::setWindowTitle(windowTitle()); dlg->QWidget::setWindowTitle(windowTitle());
dlg->show();
return dlg; // See note above.
QtHost::RunOnUIThread([this, dlg, message]() {
close();
dlg->show();
if (!message.isEmpty())
QMessageBox::information(dlg, tr("PCSX2 Settings"), message);
});
} }
void SettingsWindow::addWidget(QWidget* widget, QString title, QString icon, QString help_text) void SettingsWindow::addWidget(QWidget* widget, QString title, QString icon, QString help_text)

View File

@ -119,7 +119,7 @@ private:
void addWidget(QWidget* widget, QString title, QString icon, QString help_text); void addWidget(QWidget* widget, QString title, QString icon, QString help_text);
bool handleWheelEvent(QWheelEvent* event); bool handleWheelEvent(QWheelEvent* event);
SettingsWindow* reopen(); void reopen(const QString& message);
std::unique_ptr<INISettingsInterface> m_sif; std::unique_ptr<INISettingsInterface> m_sif;