aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4engine.cpp
diff options
context:
space:
mode:
authorFabian Kosmale <fabian.kosmale@qt.io>2021-02-20 17:33:09 +0100
committerFabian Kosmale <fabian.kosmale@qt.io>2021-03-01 14:56:39 +0100
commit8e904d9c8b36af4310070aa68ddb04cf33520b52 (patch)
treeae1144e7712b1ad140252282aad3fa4560e2de53 /src/qml/jsruntime/qv4engine.cpp
parent373abd08994f69f8215d74977e74253de6ff8cef (diff)
QML engine: Handle const QObject pointer correctly
[ChangeLog][QML][Important Behavior Changes] If a QObject pointer is passed to the QML engine and subsequently frozen with Object.freeze, modifying its QObject properties now fails and throws a TypeError. The TypeError is thrown even in non-strict mode. [ChangeLog][QML] It is now possible to pass const QObject derived pointers to QML in properties, and to call Q_INVOKABLE functions which take such pointers as arguments. If the QML engine receives such a pointer, it is treated as if the object was frozen. Fixes: QTBUG-82354 Change-Id: Ib0dbcdfb2370654505936c3cf391d87dd2c9677b Reviewed-by: Mitch Curtis <mitch.curtis@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io> Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4engine.cpp')
-rw-r--r--src/qml/jsruntime/qv4engine.cpp13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp
index 85cbca05b8..6035878fcf 100644
--- a/src/qml/jsruntime/qv4engine.cpp
+++ b/src/qml/jsruntime/qv4engine.cpp
@@ -1837,8 +1837,17 @@ QV4::ReturnedValue QV4::ExecutionEngine::fromVariant(const QVariant &variant)
a->arrayPut(ii, (v = QV4::QObjectWrapper::wrap(this, list.at(ii))));
a->setArrayLengthUnchecked(list.count());
return a.asReturnedValue();
- } else if (QMetaType(type).flags() & QMetaType::PointerToQObject) {
- return QV4::QObjectWrapper::wrap(this, *reinterpret_cast<QObject* const *>(ptr));
+ } else if (auto flags = QMetaType(type).flags(); flags & QMetaType::PointerToQObject) {
+ QV4::ReturnedValue ret = QV4::QObjectWrapper::wrap(this, *reinterpret_cast<QObject* const *>(ptr));
+ if (!flags.testFlag(QMetaType::IsConst))
+ return ret;
+ QV4::ScopedValue v(scope, ret);
+ if (auto obj = v->as<Object>()) {
+ obj->setInternalClass(obj->internalClass()->cryopreserved());
+ return obj->asReturnedValue();
+ } else {
+ return ret;
+ }
}
bool objOk;