aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/jsruntime/qv4qmlcontext.cpp
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2023-11-22 12:53:33 +0100
committerUlf Hermann <ulf.hermann@qt.io>2023-12-04 15:19:09 +0100
commit84d950bc32aa63ffa727dd8aa6bf8a65d6154e1f (patch)
tree00035aba604c6da66a8fcd91290911a50ca643e8 /src/qml/jsruntime/qv4qmlcontext.cpp
parentf187c3e5c3261d4040e4c742e32d31025409063b (diff)
QML: Let IDs in outer context override bound components' properties
This is necessary to make the usage of such IDs actually safe. If we let local properties override outer IDs, then adding local properties in later versions invalidates the ID lookups. [ChangeLog][QtQml][Important Behavior Changes] In QML documents with bound components, IDs defined in outer contexts override properties defined in inner contexts now. This is how qmlcachegen has always interpreted bound components when generating C++ code, and it is required to make access to outer IDs actually safe. The interpreter and JIT have previously preferred inner properties over outer IDs. Pick-to: 6.6 6.5 Fixes: QTBUG-119162 Change-Id: Ic5d3cc3342b4518d3fde1b800efe1b95d8e8b210 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/qml/jsruntime/qv4qmlcontext.cpp')
-rw-r--r--src/qml/jsruntime/qv4qmlcontext.cpp28
1 files changed, 26 insertions, 2 deletions
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp
index f032e953b9..7b4e5e7387 100644
--- a/src/qml/jsruntime/qv4qmlcontext.cpp
+++ b/src/qml/jsruntime/qv4qmlcontext.cpp
@@ -269,9 +269,33 @@ ReturnedValue QQmlContextWrapper::getPropertyAndBase(const QQmlContextWrapper *r
contextGetterFunction = QQmlContextWrapper::lookupScopeObjectProperty;
}
+ QQmlRefPointer<QQmlContextData> outer = context;
while (context) {
- if (auto property = searchContextProperties(v4, context, name, hasProperty, base, lookup, originalLookup, ep))
- return *property;
+ if (outer == context) {
+ if (auto property = searchContextProperties(
+ v4, context, name, hasProperty, base, lookup, originalLookup, ep)) {
+ return *property;
+ }
+
+ outer = outer->parent();
+
+ if (const auto cu = context->typeCompilationUnit(); cu && cu->componentsAreBound()) {
+ // If components are bound in this CU, we can search the whole context hierarchy
+ // of the file. Bound components' contexts override their local properties.
+ // You also can't instantiate bound components outside of their creation
+ // context. Therefore this is safe.
+
+ for (;
+ outer && outer->typeCompilationUnit() == cu;
+ outer = outer->parent()) {
+ if (auto property = searchContextProperties(
+ v4, outer, name, hasProperty, base,
+ nullptr, originalLookup, ep)) {
+ return *property;
+ }
+ }
+ }
+ }
// Search scope object
if (scopeObject) {