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();
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()
@ -324,17 +324,16 @@ void SettingsWindow::onClearSettingsClicked()
Pcsx2Config::ClearConfiguration(m_sif.get());
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.
if (!m_sif)
return this;
close();
return;
// 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());
if (FileSystem::FileExists(new_sif->GetFileName().c_str()))
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);
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)

View File

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