aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqml.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2024-01-25 11:18:17 +0100
committerUlf Hermann <ulf.hermann@qt.io>2024-01-25 18:35:05 +0100
commitafbf7b699061a38b27c91d3c95890dcc1f92ebe9 (patch)
tree5bb5f222f515d25ff977d78178f533f5ff8187c1 /src/qml/qml/qqml.cpp
parentda6680cb2eeea4c845cffac0a0f9d24e30b1625c (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.cpp41
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();