OSDN Git Service

fix possible pointer dereference in QGraphicsItemPrivate::setEnabledHelper(), QGraphi...
authorIvailo Monev <xakepa10@gmail.com>
Thu, 25 Nov 2021 10:47:06 +0000 (12:47 +0200)
committerIvailo Monev <xakepa10@gmail.com>
Thu, 25 Nov 2021 10:47:06 +0000 (12:47 +0200)
upstream commmit:
https://github.com/qt/qtbase/commit/98db99657649d4668c766eaa36b8d29c58d19754

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
src/gui/graphicsview/qgraphicsanchorlayout_p.cpp
src/gui/graphicsview/qgraphicsanchorlayout_p.h
src/gui/graphicsview/qgraphicsitem.cpp

index 77f4ae2..4d70a0e 100644 (file)
@@ -212,7 +212,7 @@ void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
         if (anchorPrivate->hasSize) {
             // Anchor has user-defined size
             prefSizeHint = anchorPrivate->preferredSize;
-        } else {
+        } else if (styleInfo) {
             // Fetch size information from style
             const Qt::Orientation orient = Qt::Orientation(QGraphicsAnchorLayoutPrivate::edgeOrientation(from->m_edge) + 1);
             qreal s = styleInfo->defaultSpacing(orient);
@@ -228,6 +228,8 @@ void AnchorData::refreshSizeHints(const QLayoutStyleInfo *styleInfo)
                     s = 0;
             }
             prefSizeHint = s;
+        } else {
+            prefSizeHint = 0;
         }
     }
 
index cc36f35..d2e6571 100644 (file)
@@ -113,7 +113,7 @@ struct AnchorData : public QSimplexVariable {
     virtual ~AnchorData();
 
     virtual void updateChildrenSizes() {}
-    void refreshSizeHints(const QLayoutStyleInfo *styleInfo = 0);
+    void refreshSizeHints(const QLayoutStyleInfo *styleInfo = nullptr);
 
 #ifndef QT_NO_DEBUG
     void dump(int indent = 2);
index bb0af26..f843253 100644 (file)
@@ -2395,23 +2395,26 @@ void QGraphicsItemPrivate::setEnabledHelper(bool newEnabled, bool explicitly, bo
 
     // Certain properties are dropped when an item is disabled.
     if (!newEnabled) {
-        if (scene && scene->mouseGrabberItem() == q_ptr)
-            q_ptr->ungrabMouse();
-        if (q_ptr->hasFocus()) {
-            // Disabling the closest non-panel ancestor of the focus item
-            // causes focus to pop to the next item, otherwise it's cleared.
-            QGraphicsItem *focusItem = scene->focusItem();
-            if (isWidget && !focusItem->isPanel() && q_ptr->isAncestorOf(focusItem)) {
-                do {
-                    if (focusItem == q_ptr) {
-                        static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
-                        break;
-                    }
-                } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
+        if (scene) {
+            if (scene->mouseGrabberItem() == q_ptr)
+                q_ptr->ungrabMouse();
+            if (q_ptr->hasFocus()) {
+                // Disabling the closest non-panel ancestor of the focus item
+                // causes focus to pop to the next item, otherwise it's cleared.
+                QGraphicsItem *focusItem = scene->focusItem();
+                bool clear = true;
+                if (isWidget && !focusItem->isPanel() && q_ptr->isAncestorOf(focusItem)) {
+                    do {
+                        if (focusItem == q_ptr) {
+                            clear = !static_cast<QGraphicsWidget *>(q_ptr)->focusNextPrevChild(true);
+                            break;
+                        }
+                    } while ((focusItem = focusItem->parentWidget()) && !focusItem->isPanel());
+                }
+                // Clear focus if previous steps didn't move it to another widget
+                if (clear)
+                    q_ptr->clearFocus();
             }
-            // Clear focus if previous steps didn't move it to another widget
-            if (q_ptr->hasFocus())
-                q_ptr->clearFocus();
         }
         if (q_ptr->isSelected())
             q_ptr->setSelected(false);
@@ -6981,14 +6984,14 @@ void QGraphicsItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
             if ((item->flags() & ItemIsMovable) && !QGraphicsItemPrivate::movableAncestorIsSelected(item)) {
                 QPointF currentParentPos;
                 QPointF buttonDownParentPos;
-                if (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorIgnoresTransformations) {
+                if (view && (item->d_ptr->ancestorFlags & QGraphicsItemPrivate::AncestorIgnoresTransformations)) {
                     // Items whose ancestors ignore transformations need to
                     // map screen coordinates to local coordinates, then map
                     // those to the parent.
                     QTransform viewToItemTransform = (item->deviceTransform(view->viewportTransform())).inverted();
                     currentParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->screenPos()))));
                     buttonDownParentPos = mapToParent(viewToItemTransform.map(QPointF(view->mapFromGlobal(event->buttonDownScreenPos(Qt::LeftButton)))));
-                } else if (item->flags() & ItemIgnoresTransformations) {
+                } else if (view && (item->flags() & ItemIgnoresTransformations)) {
                     // Root items that ignore transformations need to
                     // calculate their diff by mapping viewport coordinates
                     // directly to parent coordinates.