NUVIE: Fix Ultima 6 crash on loading save

Fix a use-after-free bug. The chain of events causing it is as follows:

In-game the user changes the current view (e.g. by pressing TAB to
go to inventory view). The user next presses ESC to open the
GameMenuDialog and then clicks the "Load Game" button. A save slot is
selected and then loaded.

The resulting call chain is:

GUI_Button::Activate_button()
  GameMenuDialog::callback()
    GameMenuDialog::close_dialog() <-- This marks GameMenuDialog
                                       for deletion by the GUI
    g_engine->loadGameDialog()
      GUI::AddWidget() <-------------- This deletes GameMenuDialog
                                       and its children, including
                                       the "Load Game" button

Control then returns to GUI_Button::Activate_button() with "this"
containing the address of the freed button.

An attempt to call Redraw() finally dereferences the invalid pointer.

This is fixed by calling loadGameDialog() before close_dialog().
This commit is contained in:
PushmePullyu 2023-03-13 22:15:38 +01:00 committed by Paul Gilbert
parent 89c843b286
commit 05ae18340d

View File

@ -148,8 +148,8 @@ GUI_status GameMenuDialog::callback(uint16 msg, GUI_CallBack *caller, void *data
close_dialog();
g_engine->saveGameDialog();
} else if (caller == load_button) {
close_dialog();
g_engine->loadGameDialog();
close_dialog();
} else if (caller == video_button) {
GUI_Widget *video_dialog;
video_dialog = (GUI_Widget *) new VideoDialog(this);