diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-01-02 18:24:13 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-01-06 13:31:57 +0100 |
commit | 6fa617524a6d0a2bc988e2dc70e8d719d1b9c282 (patch) | |
tree | ddfabea02cf1692a1430c22f41fab866dbacd5db | |
parent | c3de85efb9f354907a6c74889d15dacd0fa1eda7 (diff) |
Avoid oob access on Array.concat
As we have already determined that we're past the end of the allocated
space on the source object by checking os->values.alloc, we should
conclude that all the remaining values are undefined.
Fixes: QTBUG-81037
Change-Id: I664f22b7eb37c26061e8a9e2f88bcf2a7b6e09f3
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r-- | src/qml/jsruntime/qv4arraydata.cpp | 2 | ||||
-rw-r--r-- | tests/auto/qml/qjsengine/tst_qjsengine.cpp | 21 |
2 files changed, 22 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4arraydata.cpp b/src/qml/jsruntime/qv4arraydata.cpp index 654d33b8d1..36a53a7057 100644 --- a/src/qml/jsruntime/qv4arraydata.cpp +++ b/src/qml/jsruntime/qv4arraydata.cpp @@ -586,7 +586,7 @@ uint ArrayData::append(Object *obj, ArrayObject *otherObj, uint n) obj->arrayPut(oldSize, os->values.data() + os->offset, chunk); toCopy -= chunk; if (toCopy) - obj->arrayPut(oldSize + chunk, os->values.data(), toCopy); + obj->setArrayLength(oldSize + chunk + toCopy); } return oldSize + n; diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index f1ff396d4f..59319bead2 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -252,6 +252,7 @@ private slots: void interrupt(); void triggerBackwardJumpWithDestructuring(); + void arrayConcatOnSparseArray(); public: Q_INVOKABLE QJSValue throwingCppMethod1(); @@ -4961,6 +4962,26 @@ void tst_QJSEngine::triggerBackwardJumpWithDestructuring() QVERIFY(!value.isError()); } +void tst_QJSEngine::arrayConcatOnSparseArray() +{ + QJSEngine engine; + engine.installExtensions(QJSEngine::GarbageCollectionExtension); + const auto value = engine.evaluate( + "(function() {\n" + " const v4 = [1,2,3];\n" + " const v7 = [4,5];\n" + " v7.length = 1337;\n" + " const v9 = v4.concat(v7);\n" + " gc();\n" + " return v9;\n" + "})();"); + QCOMPARE(value.property("length").toInt(), 1340); + for (int i = 0; i < 5; ++i) + QCOMPARE(value.property(i).toInt(), i + 1); + for (int i = 5; i < 1340; ++i) + QVERIFY(value.property(i).isUndefined()); +} + QTEST_MAIN(tst_QJSEngine) #include "tst_qjsengine.moc" |