diff options
| author | Ulf Hermann <ulf.hermann@qt.io> | 2024-04-03 14:33:56 +0200 |
|---|---|---|
| committer | Ulf Hermann <ulf.hermann@qt.io> | 2024-04-09 08:28:01 +0200 |
| commit | f4e493a9cb8901468d2b8baf2d84487db9798ec2 (patch) | |
| tree | 775a4c7e441cca45c8f90be6dd90b72b803d1865 | |
| parent | 73eeb35f09fd1ea846bb0f5ce507316f587fda9f (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.h | 44 | ||||
| -rw-r--r-- | tests/auto/qml/qjsengine/tst_qjsengine.cpp | 22 |
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" |
