diff options
author | Andreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com> | 2009-09-04 09:56:43 (GMT) |
---|---|---|
committer | Andreas Aardal Hanssen <andreas.aardal.hanssen@nokia.com> | 2009-09-04 13:33:57 (GMT) |
commit | f7be6402e089aefd445a5ab98912ff5aea511cea (patch) | |
tree | b7bd2b10c84bdb08e24f2269cc21cc53a4562e7a /src/gui/graphicsview | |
parent | 7d41759f87db72ff9b9ff1d8ce017f466440f2ef (diff) | |
download | Qt-f7be6402e089aefd445a5ab98912ff5aea511cea.zip Qt-f7be6402e089aefd445a5ab98912ff5aea511cea.tar.gz Qt-f7be6402e089aefd445a5ab98912ff5aea511cea.tar.bz2 |
Fix crashes when moving descendents during destruction.
This fix prevents crashes in
QGraphicsItem caused by calls to pure virtual functions as an item
tries to access its dying parent. This happens when an item is moved
by an ancestor during this ancestor's destructor.
Autotests included.
Reviewed-by: bnilsen
Diffstat (limited to 'src/gui/graphicsview')
-rw-r--r-- | src/gui/graphicsview/qgraphicsitem.cpp | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/src/gui/graphicsview/qgraphicsitem.cpp b/src/gui/graphicsview/qgraphicsitem.cpp index 16a9a0a..eae3e63 100644 --- a/src/gui/graphicsview/qgraphicsitem.cpp +++ b/src/gui/graphicsview/qgraphicsitem.cpp @@ -4770,7 +4770,7 @@ void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &n { Q_ASSERT(inSetPosHelper); - if (!(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) + if (inDestructor || !(ancestorFlags & QGraphicsItemPrivate::AncestorClipsChildren)) return; // Not clipped by any ancestor. // Find closest clip ancestor and transform. @@ -4784,13 +4784,15 @@ void QGraphicsItemPrivate::updateCachedClipPathFromSetPosHelper(const QPointF &n thisToParentTransform *= clipParent->d_ptr->transformToParent(); clipParent = clipParent->d_ptr->parent; } - if (clipParent && clipParent->d_ptr->inDestructor) - return; - // thisToParentTransform is now the same as q->itemTransform(clipParent), except - // that the new position (which is not yet set on the item) is taken into account. - Q_ASSERT(clipParent); - Q_ASSERT(clipParent->d_ptr->flags & QGraphicsItem::ItemClipsChildrenToShape); + // Ensure no parents are currently being deleted. This can only + // happen if the item is moved by a dying ancestor. + QGraphicsItem *p = clipParent; + while (p) { + if (p->d_ptr->inDestructor) + return; + p = p->d_ptr->parent; + } // From here everything is calculated in clip parent's coordinates. const QRectF parentBoundingRect(clipParent->boundingRect()); @@ -6852,6 +6854,8 @@ void QGraphicsItem::removeFromIndex() */ void QGraphicsItem::prepareGeometryChange() { + if (d_ptr->inDestructor) + return; if (d_ptr->scene) { d_ptr->scene->d_func()->dirtyGrowingItemsBoundingRect = true; d_ptr->geometryChanged = 1; |