aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2022-11-29 08:22:01 +0100
committerUlf Hermann <ulf.hermann@qt.io>2022-11-29 09:42:06 +0100
commit5595809245cfedeb86657277b8354f45ddda2528 (patch)
treeb9565d428fd548bfc3c32eba7273d0c3304981de
parent6656567a4085e3d6de01226fb7b1ec16ee7ba08c (diff)
QQmlNotifier: Guard against broken meta objects when disconnecting
Some classes may be unable to produce a metaObject via the string casting method we employ when invalidating the interceptor metaObject. Ignore those. Furthermore, qt_metacast() may produce a different object than the one we called it on. Accept that. Finally, we don't have to check the topmost QMetaObject because we already know it's invalid. Fixes: QTBUG-108906 Change-Id: Id935d06beead4239381093f2f090d4a6a244034b Reviewed-by: Zoltan Gera <zoltan.gera@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r--src/qml/qml/qqmlnotifier_p.h9
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp4
2 files changed, 8 insertions, 5 deletions
diff --git a/src/qml/qml/qqmlnotifier_p.h b/src/qml/qml/qqmlnotifier_p.h
index 02f9017509..844766a633 100644
--- a/src/qml/qml/qqmlnotifier_p.h
+++ b/src/qml/qml/qqmlnotifier_p.h
@@ -172,12 +172,15 @@ void QQmlNotifierEndpoint::disconnect()
if (next) next->prev = prev;
if (prev) *prev = next;
- if (sourceSignal != -1) {
+ if (sourceSignal != -1 && needsConnectNotify) {
QObject * const obj = senderAsObject();
Q_ASSERT(obj);
QObjectPrivate * const priv = QObjectPrivate::get(obj);
- if (needsConnectNotify)
- priv->disconnectNotify(QMetaObjectPrivate::signal(obj->metaObject(), sourceSignal));
+
+ // In some degenerate cases an object being destructed might be unable
+ // to produce a metaObject(). Therefore we check here.
+ if (const QMetaObject *mo = obj->metaObject())
+ priv->disconnectNotify(QMetaObjectPrivate::signal(mo, sourceSignal));
}
setSender(0x0);
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 7ce1a48708..05b9328d99 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -349,7 +349,7 @@ bool QQmlInterceptorMetaObject::doIntercept(QMetaObject::Call c, int id, void **
static QMetaObject *stringCastMetaObject(QObject *o, const QMetaObject *top)
{
for (const QMetaObject *mo = top; mo; mo = mo->superClass()) {
- if (o->qt_metacast(mo->className()) == o)
+ if (o->qt_metacast(mo->className()) != nullptr)
return const_cast<QMetaObject *>(mo);
}
return nullptr;
@@ -361,7 +361,7 @@ QMetaObject *QQmlInterceptorMetaObject::toDynamicMetaObject(QObject *o)
metaObject = cache->createMetaObject();
if (Q_UNLIKELY(metaObject.tag() == MetaObjectInvalid))
- return stringCastMetaObject(o, metaObject.data());
+ return stringCastMetaObject(o, metaObject->superClass());
// ### Qt7: The const_cast is only due to toDynamicMetaObject having the wrong return type.
// It should be const QMetaObject *. Fix this.