Avoid dangling QGuiApplicationPrivate pointer

The static self pointer of QGuiApplicationPrivate was not reset at
destruction (in constrast to the corresponding
QGuiApplication::self). This could cause crashes when calling Qt API
after QGuiApplication destruction.

Fixing this revealed an issue with QGuiApplication::font(), which
would assert QGuiApplicationPrivate::self. But the QApplication
autotest actually calls this function with no QApplication
instance. That autotest passes only coincidentally, since another
QApplication instance has been created and deleted already, and
the dangling self pointer of that instance was never reset.

To improve the robustness of the api, replace the assert/crash with
just a warning and return an "empty" QFont.

(The assert was added for 5.0 for QTBUG-28306 in order to give a nicer
warning when mixing QWidget and QtCore/GuiApplication. However it
never got that effect in practice, since that issue was fixed at the
same time by another, better patch for the duplicate bug QTBUG-28076).

Fixes: QTBUG-81954
Change-Id: I3fa6cad1625a3e70631b5170d53119d63492b534
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
This commit is contained in:
Eirik Aavitsland 2020-02-07 16:00:00 +01:00
parent cd02e29319
commit 8e74bf4d4a

View File

@ -1727,6 +1727,8 @@ QGuiApplicationPrivate::~QGuiApplicationPrivate()
window_list.clear(); window_list.clear();
screen_list.clear(); screen_list.clear();
self = nullptr;
} }
#if 0 #if 0
@ -3401,8 +3403,11 @@ void QGuiApplicationPrivate::applyWindowGeometrySpecificationTo(QWindow *window)
*/ */
QFont QGuiApplication::font() QFont QGuiApplication::font()
{ {
Q_ASSERT_X(QGuiApplicationPrivate::self, "QGuiApplication::font()", "no QGuiApplication instance");
const auto locker = qt_scoped_lock(applicationFontMutex); const auto locker = qt_scoped_lock(applicationFontMutex);
if (!QGuiApplicationPrivate::self && !QGuiApplicationPrivate::app_font) {
qWarning("QGuiApplication::font(): no QGuiApplication instance and no application font set.");
return QFont(); // in effect: QFont((QFontPrivate*)nullptr), so no recursion
}
initFontUnlocked(); initFontUnlocked();
return *QGuiApplicationPrivate::app_font; return *QGuiApplicationPrivate::app_font;
} }