aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2024-04-03 14:33:56 +0200
committerUlf Hermann <ulf.hermann@qt.io>2024-04-09 08:28:01 +0200
commitf4e493a9cb8901468d2b8baf2d84487db9798ec2 (patch)
tree775a4c7e441cca45c8f90be6dd90b72b803d1865
parent73eeb35f09fd1ea846bb0f5ce507316f587fda9f (diff)
V4: Don't call methods on nullptr
The root node of a sparse array can be null. Fixes: QTBUG-123596 Change-Id: I5ea7fd73aeec460082d0cf19c7fc8a01993ed1f9 Reviewed-by: Semih Yavuz <semih.yavuz@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> (cherry picked from commit e221e1e942f58750af0a93232354a2ad35c74bcf) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> (cherry picked from commit 590db8ac18f92c594ff7dbf4b4c020aaec546c44) (cherry picked from commit 08a318b3dc377a0a6fea88332ceebf166ac741f1) (cherry picked from commit 1a5ffffcb05effb68e33ef4b45376d2b8d9b3ff0)
-rw-r--r--src/qml/jsruntime/qv4sparsearray_p.h44
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp22
2 files changed, 48 insertions, 18 deletions
diff --git a/src/qml/jsruntime/qv4sparsearray_p.h b/src/qml/jsruntime/qv4sparsearray_p.h
index e41d905bc2..2bdc4aaa2e 100644
--- a/src/qml/jsruntime/qv4sparsearray_p.h
+++ b/src/qml/jsruntime/qv4sparsearray_p.h
@@ -146,8 +146,8 @@ struct Q_QML_EXPORT SparseArray
{
SparseArray();
~SparseArray() {
- if (root())
- freeTree(header.left, Q_ALIGNOF(SparseArrayNode));
+ if (SparseArrayNode *n = root())
+ freeTree(n, Q_ALIGNOF(SparseArrayNode));
}
SparseArray(const SparseArray &other);
@@ -323,37 +323,45 @@ inline QList<int> SparseArray::keys() const
inline const SparseArrayNode *SparseArray::lowerBound(uint akey) const
{
- const SparseArrayNode *lb = root()->lowerBound(akey);
- if (!lb)
- lb = end();
- return lb;
+ if (SparseArrayNode *n = root()) {
+ if (const SparseArrayNode *lb = n->lowerBound(akey))
+ return lb;
+ }
+
+ return end();
}
inline SparseArrayNode *SparseArray::lowerBound(uint akey)
{
- SparseArrayNode *lb = root()->lowerBound(akey);
- if (!lb)
- lb = end();
- return lb;
+ if (SparseArrayNode *n = root()) {
+ if (SparseArrayNode *lb = n->lowerBound(akey))
+ return lb;
+ }
+
+ return end();
}
inline const SparseArrayNode *SparseArray::upperBound(uint akey) const
{
- const SparseArrayNode *ub = root()->upperBound(akey);
- if (!ub)
- ub = end();
- return ub;
+ if (SparseArrayNode *n = root()) {
+ if (const SparseArrayNode *ub = n->upperBound(akey))
+ return ub;
+ }
+
+ return end();
}
inline SparseArrayNode *SparseArray::upperBound(uint akey)
{
- SparseArrayNode *ub = root()->upperBound(akey);
- if (!ub)
- ub = end();
- return ub;
+ if (SparseArrayNode *n = root()) {
+ if (SparseArrayNode *ub = n->upperBound(akey))
+ return ub;
+ }
+
+ return end();
}
}
diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
index 8e7958c3ef..2b1b3e735c 100644
--- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp
+++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp
@@ -275,6 +275,8 @@ private slots:
void spreadNoOverflow();
+ void deleteFromSparseArray();
+
public:
Q_INVOKABLE QJSValue throwingCppMethod1();
Q_INVOKABLE void throwingCppMethod2();
@@ -5428,6 +5430,26 @@ void tst_QJSEngine::spreadNoOverflow()
QCOMPARE(result.errorType(), QJSValue::RangeError);
}
+void tst_QJSEngine::deleteFromSparseArray()
+{
+ QJSEngine engine;
+
+ // Should not crash
+ const QJSValue result = engine.evaluate(QLatin1String(R"((function() {
+ let o = [];
+ o[10000] = 10;
+ o[20000] = 20;
+ for (let k in o)
+ delete o[k];
+ return o;
+ })())"));
+
+ QVERIFY(result.isArray());
+ QCOMPARE(result.property("length").toNumber(), 20001);
+ QVERIFY(result.property(10000).isUndefined());
+ QVERIFY(result.property(20000).isUndefined());
+}
+
QTEST_MAIN(tst_QJSEngine)
#include "tst_qjsengine.moc"