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



commit 87625c2b0afea2930109aae52cc23e18e08e590b
Author: Mike Fleetwood <mike fleetwood googlemail com>
Date:   Wed Aug 29 14:35:47 2012 +0100

    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

 include/Dialog_Base_Partition.h |    2 ++
 src/Dialog_Base_Partition.cc    |   12 +++++++++---
 2 files changed, 11 insertions(+), 3 deletions(-)
---
diff --git a/include/Dialog_Base_Partition.h b/include/Dialog_Base_Partition.h
index 4793faf..56e5ebd 100644
--- a/include/Dialog_Base_Partition.h
+++ b/include/Dialog_Base_Partition.h
@@ -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 ;
 
diff --git a/src/Dialog_Base_Partition.cc b/src/Dialog_Base_Partition.cc
index df5666f..54a98c9 100644
--- a/src/Dialog_Base_Partition.cc
+++ b/src/Dialog_Base_Partition.cc
@@ -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;
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]