From 9e706a36a08dce0d6434cc3186961bcf813533c0 Mon Sep 17 00:00:00 2001 From: Friedrich Beckmann Date: Tue, 3 Oct 2017 21:59:51 +0200 Subject: Fix bug: crash - iterator corrupted by removing objects from container On MacOS El Capitan with XCode 7.3 inkscape crashes when a second item is drawn in the drawing area. The crash is triggered by clearing the selection from the previous drawing activity. The reason for the crash is that the iterator is corrupted because during iteration the objects are removed from the container. This patch uses a safe way to remove items from the container and going to the next iteration. Using this patch, inkscape does not crash anymore. --- src/object-set.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'src/object-set.cpp') diff --git a/src/object-set.cpp b/src/object-set.cpp index 8fcb4215e..55da22bdf 100644 --- a/src/object-set.cpp +++ b/src/object-set.cpp @@ -104,14 +104,18 @@ void ObjectSet::_removeDescendantsFromSet(SPObject *object) { } } -void ObjectSet::_remove(SPObject *object) { +void ObjectSet::_disconnect(SPObject *object) { _releaseConnections[object].disconnect(); _releaseConnections.erase(object); - _container.get().erase(object); _remove3DBoxesRecursively(object); _releaseSignals(object); } +void ObjectSet::_remove(SPObject *object) { + _disconnect(object); + _container.get().erase(object); +} + void ObjectSet::_add(SPObject *object) { _releaseConnections[object] = object->connectRelease(sigc::hide_return(sigc::mem_fun(*this, &ObjectSet::remove))); _container.push_back(object); @@ -120,8 +124,10 @@ void ObjectSet::_add(SPObject *object) { } void ObjectSet::_clear() { - for (auto object: _container) { - _remove(object); + MultiIndexContainer::iterator it = _container.begin(); + while (it != _container.end()){ + _disconnect(*it); + it = _container.erase(it); } } -- cgit v1.2.3 From a920a212fa3436801f27f75051ab47e36c21e3a2 Mon Sep 17 00:00:00 2001 From: Friedrich Beckmann Date: Wed, 4 Oct 2017 11:35:10 +0200 Subject: selection clear: First disconnect, then clear As proposed by Marc, the objects are first disconnected and then all elements are removed from the container via container.clear. This also avoids the corruption of the iterator as the container is not modified during the iterations. --- src/object-set.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'src/object-set.cpp') diff --git a/src/object-set.cpp b/src/object-set.cpp index 55da22bdf..36ddac350 100644 --- a/src/object-set.cpp +++ b/src/object-set.cpp @@ -124,11 +124,9 @@ void ObjectSet::_add(SPObject *object) { } void ObjectSet::_clear() { - MultiIndexContainer::iterator it = _container.begin(); - while (it != _container.end()){ - _disconnect(*it); - it = _container.erase(it); - } + for (auto object: _container) + _disconnect(object); + _container.clear(); } SPObject *ObjectSet::_getMutualAncestor(SPObject *object) { -- cgit v1.2.3