|
|
383017 |
From 5a7aa7881fa2c7abffb3d34a6b642fe4efcadbf4 Mon Sep 17 00:00:00 2001
|
|
|
383017 |
From: Fabian Kosmale <fabian.kosmale@qt.io>
|
|
|
383017 |
Date: Thu, 17 Dec 2020 11:22:34 +0100
|
|
|
383017 |
Subject: [PATCH 21/28] QML: Fix proxy iteration
|
|
|
383017 |
|
|
|
383017 |
If the target of a proxy was extensible, we did not set the
|
|
|
383017 |
iteratorTarget to its correct value, and thus the ForInIteratorObject
|
|
|
383017 |
would not be usable.
|
|
|
383017 |
|
|
|
383017 |
Fixes: QTBUG-86323
|
|
|
383017 |
Change-Id: Id1924ac4087bab38c006b8eba92b619b79d36b7a
|
|
|
383017 |
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
|
|
383017 |
(cherry picked from commit dd740d6b3469448dc1fd31c1742781e923e9f274)
|
|
|
383017 |
---
|
|
|
383017 |
src/qml/jsruntime/qv4proxy.cpp | 8 +++--
|
|
|
383017 |
.../qqmlecmascript/data/proxyIteration.qml | 29 +++++++++++++++++++
|
|
|
383017 |
.../qml/qqmlecmascript/tst_qqmlecmascript.cpp | 10 +++++++
|
|
|
383017 |
3 files changed, 45 insertions(+), 2 deletions(-)
|
|
|
383017 |
create mode 100644 tests/auto/qml/qqmlecmascript/data/proxyIteration.qml
|
|
|
383017 |
|
|
|
383017 |
diff --git a/src/qml/jsruntime/qv4proxy.cpp b/src/qml/jsruntime/qv4proxy.cpp
|
|
|
383017 |
index 1505eae426..8bfc9fc3ba 100644
|
|
|
383017 |
--- a/src/qml/jsruntime/qv4proxy.cpp
|
|
|
383017 |
+++ b/src/qml/jsruntime/qv4proxy.cpp
|
|
|
383017 |
@@ -624,8 +624,10 @@ OwnPropertyKeyIterator *ProxyObject::virtualOwnPropertyKeys(const Object *m, Val
|
|
|
383017 |
else
|
|
|
383017 |
targetNonConfigurableKeys->push_back(keyAsValue);
|
|
|
383017 |
}
|
|
|
383017 |
- if (target->isExtensible() && targetNonConfigurableKeys->getLength() == 0)
|
|
|
383017 |
+ if (target->isExtensible() && targetNonConfigurableKeys->getLength() == 0) {
|
|
|
383017 |
+ *iteratorTarget = *m;
|
|
|
383017 |
return new ProxyObjectOwnPropertyKeyIterator(trapKeys);
|
|
|
383017 |
+ }
|
|
|
383017 |
|
|
|
383017 |
ScopedArrayObject uncheckedResultKeys(scope, scope.engine->newArrayObject());
|
|
|
383017 |
uncheckedResultKeys->copyArrayData(trapKeys);
|
|
|
383017 |
@@ -639,8 +641,10 @@ OwnPropertyKeyIterator *ProxyObject::virtualOwnPropertyKeys(const Object *m, Val
|
|
|
383017 |
}
|
|
|
383017 |
}
|
|
|
383017 |
|
|
|
383017 |
- if (target->isExtensible())
|
|
|
383017 |
+ if (target->isExtensible()) {
|
|
|
383017 |
+ *iteratorTarget = *m;
|
|
|
383017 |
return new ProxyObjectOwnPropertyKeyIterator(trapKeys);
|
|
|
383017 |
+ }
|
|
|
383017 |
|
|
|
383017 |
len = targetConfigurableKeys->getLength();
|
|
|
383017 |
for (uint i = 0; i < len; ++i) {
|
|
|
383017 |
diff --git a/tests/auto/qml/qqmlecmascript/data/proxyIteration.qml b/tests/auto/qml/qqmlecmascript/data/proxyIteration.qml
|
|
|
383017 |
new file mode 100644
|
|
|
383017 |
index 0000000000..affba7d9f1
|
|
|
383017 |
--- /dev/null
|
|
|
383017 |
+++ b/tests/auto/qml/qqmlecmascript/data/proxyIteration.qml
|
|
|
383017 |
@@ -0,0 +1,29 @@
|
|
|
383017 |
+import QtQml 2
|
|
|
383017 |
+
|
|
|
383017 |
+QtObject {
|
|
|
383017 |
+ id: root
|
|
|
383017 |
+ property int sum
|
|
|
383017 |
+ Component.onCompleted: {
|
|
|
383017 |
+ const target = { prop1: 1, prop2: 2, prop3: 3 };
|
|
|
383017 |
+ const handler = {
|
|
|
383017 |
+ get: function(target, key) {
|
|
|
383017 |
+ return target[key]+1;
|
|
|
383017 |
+ },
|
|
|
383017 |
+ ownKeys: function() {
|
|
|
383017 |
+ return ["prop1", "prop3"];
|
|
|
383017 |
+ },
|
|
|
383017 |
+ getOwnPropertyDescriptor: function(target, key) {
|
|
|
383017 |
+ return {
|
|
|
383017 |
+ value: this.get(target, key),
|
|
|
383017 |
+ enumerable: true,
|
|
|
383017 |
+ configurable: true
|
|
|
383017 |
+ };
|
|
|
383017 |
+ }
|
|
|
383017 |
+ };
|
|
|
383017 |
+ const proxy = new Proxy(target, handler);
|
|
|
383017 |
+ for (var prop in proxy) {
|
|
|
383017 |
+ root.sum += proxy[prop] // prop2 gets skipped, the values of 1 and 3 get incremented
|
|
|
383017 |
+ }
|
|
|
383017 |
+ // so root.sum should be 6 now
|
|
|
383017 |
+ }
|
|
|
383017 |
+}
|
|
|
383017 |
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
|
|
|
383017 |
index 3a9d1bfb4c..9198d3bebf 100644
|
|
|
383017 |
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
|
|
|
383017 |
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
|
|
|
383017 |
@@ -382,6 +382,7 @@ private slots:
|
|
|
383017 |
void semicolonAfterProperty();
|
|
|
383017 |
void hugeStack();
|
|
|
383017 |
void variantConversionMethod();
|
|
|
383017 |
+ void proxyIteration();
|
|
|
383017 |
void proxyHandlerTraps();
|
|
|
383017 |
void gcCrashRegressionTest();
|
|
|
383017 |
|
|
|
383017 |
@@ -9306,6 +9307,15 @@ void tst_qqmlecmascript::variantConversionMethod()
|
|
|
383017 |
QCOMPARE(obj.funcCalled, QLatin1String("QModelIndex"));
|
|
|
383017 |
}
|
|
|
383017 |
|
|
|
383017 |
+void tst_qqmlecmascript::proxyIteration()
|
|
|
383017 |
+{
|
|
|
383017 |
+ QQmlEngine engine;
|
|
|
383017 |
+ QQmlComponent component(&engine, testFileUrl("proxyIteration.qml"));
|
|
|
383017 |
+ QScopedPointer<QObject> root(component.create());
|
|
|
383017 |
+ QVERIFY2(root != nullptr, qPrintable(component.errorString()));
|
|
|
383017 |
+ QCOMPARE(root->property("sum").toInt(), 6);
|
|
|
383017 |
+}
|
|
|
383017 |
+
|
|
|
383017 |
void tst_qqmlecmascript::proxyHandlerTraps()
|
|
|
383017 |
{
|
|
|
383017 |
const QString expression = QStringLiteral(R"SNIPPET(
|
|
|
383017 |
--
|
|
|
383017 |
2.31.1
|
|
|
383017 |
|