From 293f82daa07bbc357940e5dd214f7c534bab0a86 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 25 Apr 2023 11:03:54 +0200 Subject: [PATCH] Don't use wx_ptr for the splash screen. Using wx_ptr in the wxApp object seems bad because in ~App wxWidgets deletes all top-level windows in `DeleteAllTLWs` so if ~wx_ptr then tries to destroy them we get a use-after-free. --- src/tools/dcpomatic.cc | 9 +++++---- src/tools/dcpomatic_editor.cc | 2 +- src/tools/dcpomatic_kdm.cc | 2 +- src/tools/dcpomatic_player.cc | 2 +- src/wx/wx_util.cc | 8 ++++---- src/wx/wx_util.h | 2 +- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index a7b3af8bc..3d944e780 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -1709,7 +1709,7 @@ private: } catch (exception& e) { - _splash.reset(); + close_splash(); error_dialog (nullptr, wxString::Format ("DCP-o-matic could not start."), std_to_wx(e.what())); } @@ -1821,7 +1821,8 @@ private: void close_splash () { - _splash.reset(); + _splash->Destroy(); + _splash = nullptr; } void config_failed_to_load (Config::LoadFailure what) @@ -1839,7 +1840,7 @@ private: /* Destroy the splash screen here, as otherwise bad things seem to happen (for reasons unknown) when we open our recreate dialog, close it, *then* try to Destroy the splash (the Destroy fails). */ - _splash.reset(); + close_splash(); auto config = Config::instance(); switch (reason) { @@ -1908,7 +1909,7 @@ private: } DOMFrame* _frame = nullptr; - wx_ptr _splash; + wxSplashScreen* _splash; shared_ptr _timer; string _film_to_load; string _film_to_create; diff --git a/src/tools/dcpomatic_editor.cc b/src/tools/dcpomatic_editor.cc index 663eb8e3b..a61a17ce4 100644 --- a/src/tools/dcpomatic_editor.cc +++ b/src/tools/dcpomatic_editor.cc @@ -428,7 +428,7 @@ private: bool OnInit () override { - wx_ptr splash; + wxSplashScreen* splash; try { wxInitAllImageHandlers (); diff --git a/src/tools/dcpomatic_kdm.cc b/src/tools/dcpomatic_kdm.cc index 2e28b548a..e2993f9f2 100644 --- a/src/tools/dcpomatic_kdm.cc +++ b/src/tools/dcpomatic_kdm.cc @@ -798,7 +798,7 @@ private: bool OnInit () override { - wx_ptr splash; + wxSplashScreen* splash; try { wxInitAllImageHandlers (); diff --git a/src/tools/dcpomatic_player.cc b/src/tools/dcpomatic_player.cc index 5ce02b1ea..ab018c44b 100644 --- a/src/tools/dcpomatic_player.cc +++ b/src/tools/dcpomatic_player.cc @@ -1171,7 +1171,7 @@ private: bool OnInit () override { - wx_ptr splash; + wxSplashScreen* splash; try { wxInitAllImageHandlers (); diff --git a/src/wx/wx_util.cc b/src/wx/wx_util.cc index 7a41f66e7..f36bcdf25 100644 --- a/src/wx/wx_util.cc +++ b/src/wx/wx_util.cc @@ -537,10 +537,10 @@ setup_audio_channels_choice (wxChoice* choice, int minimum) } -wx_ptr +wxSplashScreen* maybe_show_splash () { - wx_ptr splash; + wxSplashScreen* splash; try { wxBitmap bitmap; @@ -555,9 +555,9 @@ maybe_show_splash () } #ifdef DCPOMATIC_WINDOWS /* Having wxSTAY_ON_TOP means error dialogues hide behind the splash screen on Windows, no matter what I try */ - splash.reset(bitmap, wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_NO_TIMEOUT, 0, nullptr, -1, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE | wxFRAME_NO_TASKBAR); + splash = new wxSplashScreen(bitmap, wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_NO_TIMEOUT, 0, nullptr, -1, wxDefaultPosition, wxDefaultSize, wxBORDER_SIMPLE | wxFRAME_NO_TASKBAR); #else - splash.reset(bitmap, wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_NO_TIMEOUT, 0, nullptr, -1); + splash = new wxSplashScreen(bitmap, wxSPLASH_CENTRE_ON_SCREEN | wxSPLASH_NO_TIMEOUT, 0, nullptr, -1); #endif wxYield (); } diff --git a/src/wx/wx_util.h b/src/wx/wx_util.h index e18cfc5a7..66b01640c 100644 --- a/src/wx/wx_util.h +++ b/src/wx/wx_util.h @@ -119,7 +119,7 @@ extern wxString context_translation (wxString); extern std::string string_client_data (wxClientData* o); extern wxString time_to_timecode (dcpomatic::DCPTime t, double fps); extern void setup_audio_channels_choice (wxChoice* choice, int minimum); -extern wx_ptr maybe_show_splash(); +extern wxSplashScreen* maybe_show_splash(); extern double calculate_mark_interval (double start); extern bool display_progress (wxString title, wxString task); extern bool report_errors_from_last_job (wxWindow* parent); -- 2.30.2