diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2024-01-25 11:18:17 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2024-01-25 18:35:05 +0100 |
commit | afbf7b699061a38b27c91d3c95890dcc1f92ebe9 (patch) | |
tree | 5bb5f222f515d25ff977d78178f533f5ff8187c1 /src/qml/qml/qqml.cpp | |
parent | da6680cb2eeea4c845cffac0a0f9d24e30b1625c (diff) |
QmlCompiler: Handle non-resettable undefined assignment
We need to generate an exception if undefined is assigned to a property
that can't be reset. We don't want to reject everything that can
potentially be undefined. Therefore, we use the QVariant fallback and
examine the value for undefined at run time.
Pick-to: 6.7 6.6 6.5 6.2
Change-Id: I0a034032f4522f017b452690d93319eb4bfedb1c
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/qml/qqml.cpp')
-rw-r--r-- | src/qml/qml/qqml.cpp | 41 |
1 files changed, 28 insertions, 13 deletions
diff --git a/src/qml/qml/qqml.cpp b/src/qml/qml/qqml.cpp index 46e83d532e..23cea45f9d 100644 --- a/src/qml/qml/qqml.cpp +++ b/src/qml/qml/qqml.cpp @@ -1195,10 +1195,17 @@ static ObjectPropertyResult changeObjectProperty(QV4::Lookup *l, QObject *object } template<bool StrictType = false> -static ObjectPropertyResult resetObjectProperty(QV4::Lookup *l, QObject *object) +static ObjectPropertyResult resetObjectProperty( + QV4::Lookup *l, QObject *object, QV4::ExecutionEngine *v4) { return changeObjectProperty<StrictType>(l, object, [&](const QQmlPropertyData *property) { - property->resetProperty(object, {}); + if (property->isResettable()) { + property->resetProperty(object, {}); + } else { + v4->throwError( + QLatin1String("Cannot assign [undefined] to ") + + QLatin1String(property->propType().name())); + } }); } @@ -1232,11 +1239,18 @@ static ObjectPropertyResult storeFallbackProperty(QV4::Lookup *l, QObject *objec }); } -static ObjectPropertyResult resetFallbackProperty(QV4::Lookup *l, QObject *object) +static ObjectPropertyResult resetFallbackProperty( + QV4::Lookup *l, QObject *object, const QMetaProperty *property, QV4::ExecutionEngine *v4) { return changeFallbackProperty(l, object, [&](const QMetaObject *metaObject, int coreIndex) { - void *args[] = { nullptr }; - metaObject->metacall(object, QMetaObject::ResetProperty, coreIndex, args); + if (property->isResettable()) { + void *args[] = { nullptr }; + metaObject->metacall(object, QMetaObject::ResetProperty, coreIndex, args); + } else { + v4->throwError( + QLatin1String("Cannot assign [undefined] to ") + + QLatin1String(property->typeName())); + } }); } @@ -1313,7 +1327,7 @@ static ObjectPropertyResult storeObjectAsVariant( return storeObjectProperty<true>(l, object, variant); if (!variant->isValid()) - return resetObjectProperty<true>(l, object); + return resetObjectProperty<true>(l, object, v4); if (isTypeCompatible(variant->metaType(), propType)) return storeObjectProperty<true>(l, object, variant->data()); @@ -1332,12 +1346,13 @@ static ObjectPropertyResult storeFallbackAsVariant( = reinterpret_cast<const QMetaObject *>(l->qobjectFallbackLookup.metaObject - 1); Q_ASSERT(metaObject); - const QMetaType propType = metaObject->property(l->qobjectFallbackLookup.coreIndex).metaType(); + const QMetaProperty property = metaObject->property(l->qobjectFallbackLookup.coreIndex); + const QMetaType propType = property.metaType(); if (propType == QMetaType::fromType<QVariant>()) return storeFallbackProperty(l, object, variant); - if (!propType.isValid()) - return resetFallbackProperty(l, object); + if (!variant->isValid()) + return resetFallbackProperty(l, object, &property, v4); if (isTypeCompatible(variant->metaType(), propType)) return storeFallbackProperty(l, object, variant->data()); @@ -1590,7 +1605,7 @@ void AOTCompiledContext::storeNameSloppy(uint nameIndex, void *value, QMetaType if (isTypeCompatible(type, propType)) { storeResult = storeObjectProperty(&l, qmlScopeObject, value); } else if (isUndefined(value, type)) { - storeResult = resetObjectProperty(&l, qmlScopeObject); + storeResult = resetObjectProperty(&l, qmlScopeObject, engine->handle()); } else { QVariant var(propType); QV4::ExecutionEngine *v4 = engine->handle(); @@ -1605,12 +1620,12 @@ void AOTCompiledContext::storeNameSloppy(uint nameIndex, void *value, QMetaType case ObjectLookupResult::Fallback: { const QMetaObject *metaObject = reinterpret_cast<const QMetaObject *>(l.qobjectFallbackLookup.metaObject - 1); - const QMetaType propType - = metaObject->property(l.qobjectFallbackLookup.coreIndex).metaType(); + const QMetaProperty property = metaObject->property(l.qobjectFallbackLookup.coreIndex); + const QMetaType propType = property.metaType(); if (isTypeCompatible(type, propType)) { storeResult = storeFallbackProperty(&l, qmlScopeObject, value); } else if (isUndefined(value, type)) { - storeResult = resetFallbackProperty(&l, qmlScopeObject); + storeResult = resetFallbackProperty(&l, qmlScopeObject, &property, engine->handle()); } else { QVariant var(propType); QV4::ExecutionEngine *v4 = engine->handle(); |