QSizeGrip: use a QPointer to the tracked TLW

And not a normal pointer. The problem is that in certain scenarios,
if the TLW containing a QSizeGrip changes and the old TLW gets
immediately destroyed, then the mechanism which updates the tracked
TLW is run too late, and ends up accessing a dangling pointer.
Therefore, we need to protect that pointer via a smart pointer.

Task-number: QTBUG-22867
Change-Id: Icfb051132bacde604f660ac7a98bc0a9d1022c68
Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
This commit is contained in:
Giuseppe D'Angelo 2014-09-15 16:23:02 +02:00
parent 0fa0608f70
commit b2b9fdfda0
2 changed files with 26 additions and 1 deletions

View File

@ -83,7 +83,7 @@ public:
int dyMax;
Qt::Corner m_corner;
bool gotMousePress;
QWidget *tlw;
QPointer<QWidget> tlw;
#ifdef Q_WS_MAC
void updateMacSizer(bool hide) const;
#endif

View File

@ -46,6 +46,10 @@
#include <QLineEdit>
#include <QVBoxLayout>
#include <QLabel>
#include <QMainWindow>
#include <QStatusBar>
#include <QMdiArea>
#include <QMdiSubWindow>
static inline Qt::Corner sizeGripCorner(QWidget *parent, QSizeGrip *sizeGrip)
{
@ -75,6 +79,7 @@ private slots:
void hideAndShowOnWindowStateChange_data();
void hideAndShowOnWindowStateChange();
void orientation();
void dontCrashOnTLWChange();
private:
QLineEdit *dummyWidget;
@ -191,6 +196,26 @@ void tst_QSizeGrip::orientation()
QCOMPARE(sizeGripCorner(&widget, sizeGrip), Qt::TopRightCorner);
}
void tst_QSizeGrip::dontCrashOnTLWChange()
{
// QTBUG-22867
QMdiArea mdiArea;
mdiArea.show();
QMainWindow *mw = new QMainWindow();
QMdiSubWindow *mdi = mdiArea.addSubWindow(mw);
mw->statusBar()->setSizeGripEnabled(true);
mdiArea.removeSubWindow(mw);
delete mdi;
mw->show();
// the above setup causes a change of TLW for the size grip,
// and it must not crash.
QVERIFY(QTest::qWaitForWindowExposed(&mdiArea));
QVERIFY(QTest::qWaitForWindowExposed(mw));
}
QTEST_MAIN(tst_QSizeGrip)
#include "tst_qsizegrip.moc"