Prevent crash from pressing Esc in dialogs with number entry (#682658)

Steps to reproduce:
1) Open any of these dialogs: Create New Partition, Resize/Move or
   Paste;
2) Update any of the following numeric entry fields to a different value
   using the keyboard: Free space preceding, New size or Free space
   following;
3) Press [Esc] key;
Gparted crashes.

What is happening is that the [Esc] key is leading to the dialog being
closed and calling the ~Dialog_Base_Partition() destructor.  However
after this the GTK widget is calling the on_spinbutton_value_change()
registered callbacks for the change to the other two values, on the now
just deleted object.

Fix by disconnecting the change notification callbacks in the
destructor.

Closes bug #682658 - GParted crash by pressing Esc in dialogs with
                     number entry
This commit is contained in:
Mike Fleetwood 2012-08-29 14:35:47 +01:00 committed by Curtis Gedak
parent 34cf70f41d
commit 87625c2b0a
2 changed files with 11 additions and 3 deletions

View File

@ -73,6 +73,8 @@ protected:
Gtk::OptionMenu optionmenu_alignment ;
Gtk::Menu menu_alignment ;
sigc::connection before_change_connection, size_change_connection, after_change_connection ;
//used to enable/disable OKbutton...
int ORIG_BEFORE, ORIG_SIZE, ORIG_AFTER ;

View File

@ -80,14 +80,17 @@ Dialog_Base_Partition::Dialog_Base_Partition()
//connect signalhandlers of the spinbuttons
if ( ! fixed_start )
spinbutton_before .signal_value_changed() .connect(
before_change_connection = spinbutton_before .signal_value_changed() .connect(
sigc::bind<SPINBUTTON>(
sigc::mem_fun(*this, &Dialog_Base_Partition::on_spinbutton_value_changed), BEFORE ) ) ;
else
//Initialise empty connection object for use in the destructor
before_change_connection = sigc::connection() ;
spinbutton_size .signal_value_changed() .connect(
size_change_connection = spinbutton_size .signal_value_changed() .connect(
sigc::bind<SPINBUTTON>(
sigc::mem_fun(*this, &Dialog_Base_Partition::on_spinbutton_value_changed), SIZE ) ) ;
spinbutton_after .signal_value_changed() .connect(
after_change_connection = spinbutton_after .signal_value_changed() .connect(
sigc::bind<SPINBUTTON>(
sigc::mem_fun(*this, &Dialog_Base_Partition::on_spinbutton_value_changed), AFTER ) ) ;
@ -376,6 +379,9 @@ void Dialog_Base_Partition::Check_Change()
Dialog_Base_Partition::~Dialog_Base_Partition()
{
before_change_connection .disconnect() ;
size_change_connection .disconnect() ;
after_change_connection .disconnect() ;
delete frame_resizer_base;
}