Skip to content

Commit

Permalink
Fixed crash when deleting multiple objects with manual drawing order
Browse files Browse the repository at this point in the history
Due to the way the change was handled in different places, the items
could get updated after they were deleted, leading to dereferencing a
null pointer.

Fixed by deleting items individually.

Closes mapeditor#2844
  • Loading branch information
bjorn committed Jun 24, 2020
1 parent 714746b commit f40e0ab
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 11 deletions.
18 changes: 8 additions & 10 deletions src/tiled/mapitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,9 +368,11 @@ void MapItem::documentChanged(const ChangeEvent &change)
case ChangeEvent::LayerChanged:
layerChanged(static_cast<const LayerChangeEvent&>(change).layer);
break;
case ChangeEvent::MapObjectsAboutToBeRemoved:
deleteObjectItems(static_cast<const MapObjectsEvent&>(change).mapObjects);
case ChangeEvent::MapObjectAboutToBeRemoved: {
auto &e = static_cast<const MapObjectEvent&>(change);
deleteObjectItem(e.objectGroup->objectAt(e.index));
break;
}
case ChangeEvent::MapObjectsChanged:
syncObjectItems(static_cast<const MapObjectsChangeEvent&>(change).mapObjects);
break;
Expand Down Expand Up @@ -563,15 +565,11 @@ void MapItem::objectsInserted(ObjectGroup *objectGroup, int first, int last)
/**
* Removes the map object items related to the given objects.
*/
void MapItem::deleteObjectItems(const QList<MapObject*> &objects)
void MapItem::deleteObjectItem(MapObject *object)
{
for (MapObject *o : objects) {
auto i = mObjectItems.find(o);
Q_ASSERT(i != mObjectItems.end());

delete i.value();
mObjectItems.erase(i);
}
auto item = mObjectItems.take(object);
Q_ASSERT(item);
delete item;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/tiled/mapitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ class MapItem : public QGraphicsObject
void tilesetReplaced(int index, Tileset *tileset);

void objectsInserted(ObjectGroup *objectGroup, int first, int last);
void deleteObjectItems(const QList<MapObject*> &objects);
void deleteObjectItem(MapObject *object);
void syncObjectItems(const QList<MapObject*> &objects);
void objectsIndexChanged(ObjectGroup *objectGroup, int first, int last);

Expand Down

0 comments on commit f40e0ab

Please sign in to comment.