101 lines
3.5 KiB
Diff
101 lines
3.5 KiB
Diff
|
From 810a0afe1e9bd14e4393a73bf6c299b25745dbc5 Mon Sep 17 00:00:00 2001
|
||
|
From: Richard Weickelt <richard@weickelt.de>
|
||
|
Date: Tue, 24 Nov 2020 01:14:28 +0100
|
||
|
Subject: [PATCH 13/28] Fix crash when calling hasOwnProperty() on proxy object
|
||
|
|
||
|
Property pointer p needs to be checked for nullptr value in
|
||
|
QV4::ProxyObject::virtualGetOwnProperty(). This can happen when calling
|
||
|
hasOwnProperty() or propertyIsEnumerable().
|
||
|
|
||
|
Fixes: QTBUG-88786
|
||
|
Change-Id: I43da58fed4d8656f9187213f7317f17398739e34
|
||
|
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
|
||
|
(cherry picked from commit 9b321a34490cd17c0eb043b69bd7c9d8d8f513d5)
|
||
|
Reviewed-by: Richard Weickelt <richard@weickelt.de>
|
||
|
---
|
||
|
src/qml/jsruntime/qv4proxy.cpp | 10 +++---
|
||
|
.../qml/qqmlecmascript/tst_qqmlecmascript.cpp | 31 ++++++++++++++++++-
|
||
|
2 files changed, 36 insertions(+), 5 deletions(-)
|
||
|
|
||
|
diff --git a/src/qml/jsruntime/qv4proxy.cpp b/src/qml/jsruntime/qv4proxy.cpp
|
||
|
index 24676ffd00..1505eae426 100644
|
||
|
--- a/src/qml/jsruntime/qv4proxy.cpp
|
||
|
+++ b/src/qml/jsruntime/qv4proxy.cpp
|
||
|
@@ -265,9 +265,9 @@ PropertyAttributes ProxyObject::virtualGetOwnProperty(const Managed *m, Property
|
||
|
ScopedProperty targetDesc(scope);
|
||
|
PropertyAttributes targetAttributes = target->getOwnProperty(id, targetDesc);
|
||
|
if (trapResult->isUndefined()) {
|
||
|
- p->value = Encode::undefined();
|
||
|
- if (targetAttributes == Attr_Invalid) {
|
||
|
+ if (p)
|
||
|
p->value = Encode::undefined();
|
||
|
+ if (targetAttributes == Attr_Invalid) {
|
||
|
return Attr_Invalid;
|
||
|
}
|
||
|
if (!targetAttributes.isConfigurable() || !target->isExtensible()) {
|
||
|
@@ -295,8 +295,10 @@ PropertyAttributes ProxyObject::virtualGetOwnProperty(const Managed *m, Property
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- p->value = resultDesc->value;
|
||
|
- p->set = resultDesc->set;
|
||
|
+ if (p) {
|
||
|
+ p->value = resultDesc->value;
|
||
|
+ p->set = resultDesc->set;
|
||
|
+ }
|
||
|
return resultAttributes;
|
||
|
}
|
||
|
|
||
|
diff --git a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
|
||
|
index 1e10841430..3a9d1bfb4c 100644
|
||
|
--- a/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
|
||
|
+++ b/tests/auto/qml/qqmlecmascript/tst_qqmlecmascript.cpp
|
||
|
@@ -382,7 +382,7 @@ private slots:
|
||
|
void semicolonAfterProperty();
|
||
|
void hugeStack();
|
||
|
void variantConversionMethod();
|
||
|
-
|
||
|
+ void proxyHandlerTraps();
|
||
|
void gcCrashRegressionTest();
|
||
|
|
||
|
private:
|
||
|
@@ -9306,6 +9306,35 @@ void tst_qqmlecmascript::variantConversionMethod()
|
||
|
QCOMPARE(obj.funcCalled, QLatin1String("QModelIndex"));
|
||
|
}
|
||
|
|
||
|
+void tst_qqmlecmascript::proxyHandlerTraps()
|
||
|
+{
|
||
|
+ const QString expression = QStringLiteral(R"SNIPPET(
|
||
|
+ (function(){
|
||
|
+ const target = {
|
||
|
+ prop: 47
|
||
|
+ };
|
||
|
+ const handler = {
|
||
|
+ getOwnPropertyDescriptor(target, prop) {
|
||
|
+ return { configurable: true, enumerable: true, value: 47 };
|
||
|
+ }
|
||
|
+ };
|
||
|
+ const proxy = new Proxy(target, handler);
|
||
|
+
|
||
|
+ // QTBUG-88786
|
||
|
+ if (!proxy.propertyIsEnumerable("prop"))
|
||
|
+ throw Error("FAIL: propertyisEnumerable");
|
||
|
+ if (!proxy.hasOwnProperty("prop"))
|
||
|
+ throw Error("FAIL: hasOwnProperty");
|
||
|
+
|
||
|
+ return "SUCCESS";
|
||
|
+ })()
|
||
|
+ )SNIPPET");
|
||
|
+
|
||
|
+ QJSEngine engine;
|
||
|
+ QJSValue value = engine.evaluate(expression);
|
||
|
+ QVERIFY(value.isString() && value.toString() == QStringLiteral("SUCCESS"));
|
||
|
+}
|
||
|
+
|
||
|
QTEST_MAIN(tst_qqmlecmascript)
|
||
|
|
||
|
#include "tst_qqmlecmascript.moc"
|
||
|
--
|
||
|
2.31.1
|
||
|
|