aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2025-04-10 14:52:08 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2025-04-11 19:18:30 +0000
commit0b0cb0eeab8210022b5ab6f14ec8ab489b8020d3 (patch)
tree1b5476684d77abf8ac708b5c62536572bca5be26
parent9500c23348886d3dae64b8fa2305bfab517aac12 (diff)
QtQml: Fix context traversal in QQmlProperty
We need to retrieve the object from the current context, not from the innermost one. Amends commit 21f15ede606df028479335c64c333db5fb1bb3f7 Pick-to: 6.5 Fixes: QTBUG-134778 Change-Id: I1abc24dfdbb1c2f0d61a2848ad55e441cdda54a9 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Sami Shalayel <sami.shalayel@qt.io> (cherry picked from commit a55a85ecca0220b2bf9df717ee2696dffbef331f) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit a1c345490fbdeb3b2056edd609a2d898d6927a93)
-rw-r--r--src/qml/qml/qqmlproperty.cpp2
-rw-r--r--tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp31
2 files changed, 28 insertions, 5 deletions
diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp
index f2f753ad68..d39fa28e4a 100644
--- a/src/qml/qml/qqmlproperty.cpp
+++ b/src/qml/qml/qqmlproperty.cpp
@@ -301,7 +301,7 @@ void QQmlPropertyPrivate::initProperty(QObject *obj, const QString &name,
for (auto idContext = context; idContext; idContext = idContext->parent()) {
const int objectId = idContext->propertyIndex(pathName.toString());
if (objectId != -1 && objectId < idContext->numIdValues()) {
- currentObject = context->idValue(objectId);
+ currentObject = idContext->idValue(objectId);
break;
}
}
diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
index 2635af705b..2963f66100 100644
--- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
+++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp
@@ -2428,6 +2428,7 @@ void tst_qqmlproperty::initFlags_data()
QTest::addColumn<bool>("passObject");
QTest::addColumn<QString>("name");
QTest::addColumn<QQmlPropertyPrivate::InitFlags>("flags");
+ QTest::addColumn<bool>("useInnerObject");
const QString names[] = {
QStringLiteral("foo"),
@@ -2457,7 +2458,10 @@ void tst_qqmlproperty::initFlags_data()
for (const auto &flagSet : flagSets) {
const QString rowName = QStringLiteral("%1,%2,%3")
.arg(passObject).arg(name).arg(flagSet.toInt());
- QTest::addRow("%s", qPrintable(rowName)) << passObject << name << flagSet;
+ QTest::addRow("%s", qPrintable(rowName + ",outer"))
+ << passObject << name << flagSet << false;
+ QTest::addRow("%s", qPrintable(rowName + ",inner"))
+ << passObject << name << flagSet << true;
}
}
}
@@ -2468,6 +2472,7 @@ void tst_qqmlproperty::initFlags()
QFETCH(bool, passObject);
QFETCH(QString, name);
QFETCH(QQmlPropertyPrivate::InitFlags, flags);
+ QFETCH(bool, useInnerObject);
QQmlEngine engine;
QQmlComponent c(&engine);
@@ -2479,15 +2484,31 @@ void tst_qqmlproperty::initFlags()
property int bar: 12
property alias abar: self.bar
}
- )", QUrl());
+ )", QUrl("outer"));
QVERIFY2(c.isReady(), qPrintable(c.errorString()));
QScopedPointer<QObject> o(c.create());
QVERIFY(!o.isNull());
- QQmlRefPointer<QQmlContextData> context = QQmlContextData::get(qmlContext(o.data()));
+ QObject *object = nullptr;
+
+ QScopedPointer<QObject> i;
+ if (useInnerObject) {
+ QQmlComponent c2(&engine);
+ c2.setData(R"(
+ import QtQml
+ QtObject {}
+ )", QUrl("inner"));
+ QVERIFY2(c2.isReady(), qPrintable(c2.errorString()));
+ i.reset(c2.create(qmlContext(o.data())));
+ object = i.data();
+ } else {
+ object = o.data();
+ }
+
+ QQmlRefPointer<QQmlContextData> context = QQmlContextData::get(qmlContext(object));
const QQmlProperty property = QQmlPropertyPrivate::create(
- passObject ? o.data() : nullptr, name, context, flags);
+ passObject ? object : nullptr, name, context, flags);
const bool usesId = name.startsWith(QStringLiteral("self."));
const bool hasSignal = name.endsWith(QStringLiteral("foo"))
@@ -2501,6 +2522,8 @@ void tst_qqmlproperty::initFlags()
QVERIFY(!property.isValid());
} else if (hasSignal && !(flags & QQmlPropertyPrivate::InitFlag::AllowSignal)) {
QVERIFY(!property.isValid());
+ } else if (useInnerObject && passObject) {
+ QVERIFY(!property.isValid());
} else {
QVERIFY(property.isValid());
if (name.endsWith(QStringLiteral("bar"))) {