From 02c12263ac40289afc626156358ebb705ed84a5b Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Wed, 7 May 2014 23:26:13 +0300 Subject: [PATCH] Avoid segfault if an exception is thrown while loading The Layout::add functions are called from object constructors. If an exception is thrown inside them, the constructor will abort and the object will be deleted. If that happens, it must be removed from the Layout as well, or an invalid memory access will occur later. --- source/libr2c2/layout.cpp | 52 +++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/source/libr2c2/layout.cpp b/source/libr2c2/layout.cpp index 0901382..af7304d 100644 --- a/source/libr2c2/layout.cpp +++ b/source/libr2c2/layout.cpp @@ -69,31 +69,69 @@ Driver &Layout::get_driver() const void Layout::add(Object &o) { if(objects.insert(o)) - signal_object_added.emit(o); + { + try + { + signal_object_added.emit(o); + } + catch(...) + { + objects.erase(o); + throw; + } + } } void Layout::add(Track &t) { if(objects.insert(t)) { - // Blocks must be recreated first - create_blocks(); - signal_object_added.emit(t); + try + { + // Blocks must be recreated first + create_blocks(); + signal_object_added.emit(t); + } + catch(...) + { + objects.erase(t); + create_blocks(); + throw; + } } } void Layout::add(TrackChain &g) { if(track_chains.insert(g)) - signal_track_chain_added.emit(g); + { + try + { + signal_track_chain_added.emit(g); + } + catch(...) + { + track_chains.erase(g); + throw; + } + } } void Layout::add(Block &b) { if(track_chains.insert(b)) { - b.signal_reserved.connect(sigc::bind<0>(signal_block_reserved, sigc::ref(b))); - signal_track_chain_added.emit(b); + sigc::connection conn = b.signal_reserved.connect(sigc::bind<0>(signal_block_reserved, sigc::ref(b))); + try + { + signal_track_chain_added.emit(b); + } + catch(...) + { + track_chains.erase(b); + conn.disconnect(); + throw; + } } } -- 2.45.2