diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2025-04-10 14:52:08 +0200 |
|---|---|---|
| committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2025-04-11 19:18:30 +0000 |
| commit | 0b0cb0eeab8210022b5ab6f14ec8ab489b8020d3 (patch) | |
| tree | 1b5476684d77abf8ac708b5c62536572bca5be26 | |
| parent | 9500c23348886d3dae64b8fa2305bfab517aac12 (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.cpp | 2 | ||||
| -rw-r--r-- | tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp | 31 |
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"))) { |
