diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2010-01-22 16:25:38 (GMT) |
---|---|---|
committer | Prasanth Ullattil <prasanth.ullattil@nokia.com> | 2010-01-27 15:30:25 (GMT) |
commit | 9f8272b979be69574ae7e5211219363b03d23316 (patch) | |
tree | 6a9fa19584950e9cde57254b16dab9848bc02196 /tests/auto | |
parent | 4bcc8a24129b69efa1217dd033f0af949df0bcb9 (diff) | |
download | Qt-9f8272b979be69574ae7e5211219363b03d23316.zip Qt-9f8272b979be69574ae7e5211219363b03d23316.tar.gz Qt-9f8272b979be69574ae7e5211219363b03d23316.tar.bz2 |
Potential crash when adding items from QGraphicsWidget::polishEvent().
These were processed immediately, so there was a fair chance that we
could end up doing a virtual function call on items that were not fully
constructed. This patch is also an optimization, since we never remove
anything from the vector.
Auto-test included.
Reviewed-by: Jan-Arve
Diffstat (limited to 'tests/auto')
-rw-r--r-- | tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp index c08a628e..547e7f5 100644 --- a/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp +++ b/tests/auto/qgraphicsscene/tst_qgraphicsscene.cpp @@ -270,6 +270,7 @@ private slots: void initialFocus_data(); void initialFocus(); void polishItems(); + void polishItems2(); void isActive(); void siblingIndexAlwaysValid(); @@ -3942,14 +3943,23 @@ void tst_QGraphicsScene::initialFocus() class PolishItem : public QGraphicsTextItem { public: - PolishItem(QGraphicsItem *parent = 0) : QGraphicsTextItem(parent) { } + PolishItem(QGraphicsItem *parent = 0) + : QGraphicsTextItem(parent), polished(false), deleteChildrenInPolish(true), addChildrenInPolish(false) { } + bool polished; + bool deleteChildrenInPolish; + bool addChildrenInPolish; protected: QVariant itemChange(GraphicsItemChange change, const QVariant& value) { if (change == ItemVisibleChange) { - if (value.toBool()) + polished = true; + if (deleteChildrenInPolish) qDeleteAll(childItems()); + if (addChildrenInPolish) { + for (int i = 0; i < 10; ++i) + new PolishItem(this); + } } return QGraphicsItem::itemChange(change, value); } @@ -3966,6 +3976,35 @@ void tst_QGraphicsScene::polishItems() QMetaObject::invokeMethod(&scene,"_q_polishItems"); } +void tst_QGraphicsScene::polishItems2() +{ + QGraphicsScene scene; + PolishItem *item = new PolishItem; + item->addChildrenInPolish = true; + item->deleteChildrenInPolish = true; + // These children should be deleted in the polish. + for (int i = 0; i < 20; ++i) + new PolishItem(item); + scene.addItem(item); + + // Wait for the polish event to be delivered. + QVERIFY(!item->polished); + QApplication::processEvents(); + QVERIFY(item->polished); + + // We deleted the children we added above, but we also + // added 10 new children. These should be polished in the next + // event loop iteration. + QList<QGraphicsItem *> children = item->childItems(); + QCOMPARE(children.count(), 10); + foreach (QGraphicsItem *child, children) + QVERIFY(!static_cast<PolishItem *>(child)->polished); + + QApplication::processEvents(); + foreach (QGraphicsItem *child, children) + QVERIFY(static_cast<PolishItem *>(child)->polished); +} + void tst_QGraphicsScene::isActive() { QGraphicsScene scene1; |