diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-01-13 18:36:13 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-01-29 15:39:42 +0100 |
commit | 228f854ff99719d4c8151a3b52612e74f649f2b8 (patch) | |
tree | 2c41080c864f7907d64c7dd4b0bf645248e49889 /src/qml/qml/qqmlproperty.cpp | |
parent | a82b1b278ace7a500f95473f2a873923d2d4e60a (diff) |
Get rid of global gadgetPtr in QQmlValueType
We should not keep user-created objects in global data structures. This
is inherently thread-unsafe and crashes when the user passes static data
and later unloads the same.
Instead we keep the cached gadgetPtr wrapper objects in the engine now.
Fixes: QTBUG-79553
Change-Id: I24ac3e84b572831d1d70b61b8a6001338579e284
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/qml/qml/qqmlproperty.cpp')
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index f5aae8f462..d191d07258 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -1044,13 +1044,19 @@ QVariant QQmlProperty::read(const QObject *object, const QString &name, QQmlEngi QVariant QQmlPropertyPrivate::readValueProperty() { - if (isValueType()) { - - QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType()); - Q_ASSERT(valueType); - valueType->read(object, core.coreIndex()); - return valueType->metaObject()->property(valueTypeData.coreIndex()).read(valueType); + auto doRead = [&](QQmlGadgetPtrWrapper *wrapper) { + wrapper->read(object, core.coreIndex()); + return wrapper->property(valueTypeData.coreIndex()).read(wrapper); + }; + if (isValueType()) { + if (QQmlGadgetPtrWrapper *wrapper = QQmlGadgetPtrWrapper::instance(engine, core.propType())) + return doRead(wrapper); + if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType())) { + QQmlGadgetPtrWrapper wrapper(valueType, nullptr); + return doRead(&wrapper); + } + return QVariant(); } else if (core.isQList()) { QQmlListProperty<QObject> prop; @@ -1183,10 +1189,22 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object, bool rv = false; if (valueTypeData.isValid()) { - QQmlValueType *writeBack = QQmlValueTypeFactory::valueType(core.propType()); - writeBack->read(object, core.coreIndex()); - rv = write(writeBack, valueTypeData, value, context, flags); - writeBack->write(object, core.coreIndex(), flags); + auto doWrite = [&](QQmlGadgetPtrWrapper *wrapper) { + wrapper->read(object, core.coreIndex()); + rv = write(wrapper, valueTypeData, value, context, flags); + wrapper->write(object, core.coreIndex(), flags); + }; + + QQmlGadgetPtrWrapper *wrapper = context + ? QQmlGadgetPtrWrapper::instance(context->engine, core.propType()) + : nullptr; + if (wrapper) { + doWrite(wrapper); + } else if (QQmlValueType *valueType = QQmlValueTypeFactory::valueType(core.propType())) { + QQmlGadgetPtrWrapper wrapper(valueType, nullptr); + doWrite(&wrapper); + } + } else { rv = write(object, core, value, context, flags); } |