summaryrefslogtreecommitdiffstats
path: root/src/remoteobjects/qremoteobjectsource.cpp
diff options
context:
space:
mode:
authorMichael Brasser <mbrasser@ford.com>2019-10-07 10:37:37 -0500
committerBrett Stottlemyer <bstottle@ford.com>2021-07-22 08:57:19 -0400
commit28093b4ac318209f12189efda9094797226eead1 (patch)
tree212a31372920a0ac0bcd267b608359a108d41114 /src/remoteobjects/qremoteobjectsource.cpp
parentb6730532817d9b1bc296b90ca94dbe3fdca674d4 (diff)
Fix crash when remoting QML objects with sub-objects
There are two edge cases to watch out for. First, the property metaType's metaObject() returns a nullptr, so the property QObject pointer's metaObject needs to be used instead. If the QObject is null, the property is skipped, as there is no way to get the metaobject without introducing a dependency on QtQuick. Pick-to: 6.2 5.15 Change-Id: I60ae36dffb30c840858e4d67b9980299c58354b4 Reviewed-by: Michael Brasser <michael.brasser@live.com> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/remoteobjects/qremoteobjectsource.cpp')
-rw-r--r--src/remoteobjects/qremoteobjectsource.cpp33
1 files changed, 24 insertions, 9 deletions
diff --git a/src/remoteobjects/qremoteobjectsource.cpp b/src/remoteobjects/qremoteobjectsource.cpp
index e84cf64..61e4c17 100644
--- a/src/remoteobjects/qremoteobjectsource.cpp
+++ b/src/remoteobjects/qremoteobjectsource.cpp
@@ -112,7 +112,10 @@ QRemoteObjectSourceBase::QRemoteObjectSourceBase(QObject *obj, Private *d, const
if (metaType.flags().testFlag(QMetaType::PointerToQObject)) {
auto propertyMeta = metaType.metaObject();
QObject *child = property.read(m_object).value<QObject *>();
- if (propertyMeta->inherits(&QAbstractItemModel::staticMetaObject)) {
+ const QMetaObject *meta = child ? child->metaObject() : propertyMeta;
+ if (!meta)
+ continue;
+ if (meta->inherits(&QAbstractItemModel::staticMetaObject)) {
const auto modelInfo = api->m_models.at(modelIndex++);
QAbstractItemModel *model = qobject_cast<QAbstractItemModel *>(child);
QAbstractItemAdapterSourceAPI<QAbstractItemModel, QAbstractItemModelSourceAdapter> *modelApi =
@@ -452,14 +455,21 @@ DynamicApiMap::DynamicApiMap(QObject *object, const QMetaObject *metaObject, con
const int propCount = metaObject->propertyCount();
const int propOffset = metaObject->propertyOffset();
m_properties.reserve(propCount-propOffset);
- int i = 0;
- for (i = propOffset; i < propCount; ++i) {
+ QSet<int> invalidSignals;
+ for (int i = propOffset; i < propCount; ++i) {
const QMetaProperty property = metaObject->property(i);
const auto metaType = property.metaType();
if (metaType.flags().testFlag(QMetaType::PointerToQObject)) {
auto propertyMeta = metaType.metaObject();
QObject *child = property.read(object).value<QObject *>();
- if (propertyMeta->inherits(&QAbstractItemModel::staticMetaObject)) {
+ const QMetaObject *meta = child ? child->metaObject() : propertyMeta;
+ if (!meta) {
+ const int notifyIndex = metaObject->property(i).notifySignalIndex();
+ if (notifyIndex != -1)
+ invalidSignals << notifyIndex;
+ continue;
+ }
+ if (meta->inherits(&QAbstractItemModel::staticMetaObject)) {
const QByteArray name = QByteArray::fromRawData(property.name(),
qsizetype(qstrlen(property.name())));
const QByteArray infoName = name.toUpper() + QByteArrayLiteral("_ROLES");
@@ -473,12 +483,15 @@ DynamicApiMap::DynamicApiMap(QObject *object, const QMetaObject *metaObject, con
QString::fromLatin1(property.name()),
roleInfo});
} else {
- const QMetaObject *meta = child ? child->metaObject() : propertyMeta;
QString typeName = QtRemoteObjects::getTypeNameAndMetaobjectFromClassInfo(meta);
if (typeName.isNull()) {
- typeName = QString::fromLatin1(propertyMeta->className());
+ typeName = QString::fromLatin1(meta->className());
+ if (typeName.contains(QLatin1String("QQuick")))
+ typeName.remove(QLatin1String("QQuick"));
+ else if (int index = typeName.indexOf(QLatin1String("_QMLTYPE_")))
+ typeName.truncate(index);
// TODO better way to ensure we have consistent typenames between source/replicas?
- if (typeName.endsWith(QLatin1String("Source")))
+ else if (typeName.endsWith(QLatin1String("Source")))
typeName.chop(6);
}
@@ -497,11 +510,13 @@ DynamicApiMap::DynamicApiMap(QObject *object, const QMetaObject *metaObject, con
}
const int methodCount = metaObject->methodCount();
const int methodOffset = metaObject->methodOffset();
- for (i = methodOffset; i < methodCount; ++i) {
+ for (int i = methodOffset; i < methodCount; ++i) {
const QMetaMethod mm = metaObject->method(i);
const QMetaMethod::MethodType m = mm.methodType();
if (m == QMetaMethod::Signal) {
- if (m_signals.indexOf(i) >= 0) //Already added as a property notifier
+ if (m_signals.indexOf(i) >= 0) // Already added as a property notifier
+ continue;
+ if (invalidSignals.contains(i)) // QObject with no metatype
continue;
m_signals << i;
} else if (m == QMetaMethod::Slot || m == QMetaMethod::Method)