diff options
author | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2010-01-22 16:25:38 (GMT) |
---|---|---|
committer | Bjørn Erik Nilsen <bjorn.nilsen@nokia.com> | 2010-01-22 17:45:58 (GMT) |
commit | 5f4af1b5b5a96875b42750a778dcf6695a844623 (patch) | |
tree | d2ece281dfe69bd432fcab1d3442980286c51a17 /tests/auto | |
parent | 3e51b6c872e86a5e68a8e59770fc1bc32b84da0c (diff) | |
download | Qt-5f4af1b5b5a96875b42750a778dcf6695a844623.zip Qt-5f4af1b5b5a96875b42750a778dcf6695a844623.tar.gz Qt-5f4af1b5b5a96875b42750a778dcf6695a844623.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; |