Skip to content

Commit 6bf4a0c

Browse files
authored
Merge pull request #2061 from darko1979/issue1872
Fixes a crash after a diff operation followed by a model close action.
2 parents 1a19dca + 0222575 commit 6bf4a0c

2 files changed

Lines changed: 18 additions & 2 deletions

File tree

libs/libcore/src/baseobject.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1630,7 +1630,11 @@ void BaseObject::clearDependencies()
16301630

16311631
void BaseObject::clearReferences()
16321632
{
1633-
for(auto &obj : object_refs)
1633+
/* Iterate over a snapshot: unsetDependency calls back into this->unsetReference
1634+
* which erases from object_refs, invalidating the range-for iterator. */
1635+
auto refs_snapshot = object_refs;
1636+
1637+
for(auto &obj : refs_snapshot)
16341638
obj->unsetDependency(this);
16351639

16361640
object_refs.clear();

libs/libcore/src/databasemodel.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -836,10 +836,22 @@ void DatabaseModel::destroyObjects()
836836
ritr = objects.rbegin();
837837
ritr_end = objects.rend();
838838

839+
/* Pass 1: clear all deps/refs across every object before any deletion.
840+
* This prevents dangling pointers when Relationship::destroyObjects() later
841+
* frees intermediate columns/constraints that are still referenced by other objects. */
842+
while(ritr != ritr_end)
843+
{
844+
ritr->second->clearAllDepsRefs();
845+
ritr++;
846+
}
847+
848+
ritr = objects.rbegin();
849+
ritr_end = objects.rend();
850+
851+
/* Pass 2: now safe to delete — no object can hold live pointers to another. */
839852
while(ritr != ritr_end)
840853
{
841854
object = ritr->second;
842-
object->clearAllDepsRefs();
843855
ritr++;
844856

845857
// We ignore the database itself, permission objects (destroyed separetely) and table children objects

0 commit comments

Comments
 (0)