[Scummvm-git-logs] scummvm master -> 05ae18340d5a45f5cbfd3ae52c2be7bb885bfa1d

dreammaster noreply at scummvm.org
Tue Mar 14 03:08:12 UTC 2023


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
05ae18340d NUVIE: Fix Ultima 6 crash on loading save


Commit: 05ae18340d5a45f5cbfd3ae52c2be7bb885bfa1d
    https://github.com/scummvm/scummvm/commit/05ae18340d5a45f5cbfd3ae52c2be7bb885bfa1d
Author: PushmePullyu (127053144+PushmePullyu at users.noreply.github.com)
Date: 2023-03-13T20:08:07-07:00

Commit Message:
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().

Changed paths:
    engines/ultima/nuvie/menus/game_menu_dialog.cpp


diff --git a/engines/ultima/nuvie/menus/game_menu_dialog.cpp b/engines/ultima/nuvie/menus/game_menu_dialog.cpp
index 14270d4a36c..24bf10fb95d 100644
--- a/engines/ultima/nuvie/menus/game_menu_dialog.cpp
+++ b/engines/ultima/nuvie/menus/game_menu_dialog.cpp
@@ -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);




More information about the Scummvm-git-logs mailing list