aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-01-02 18:24:13 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-01-06 13:31:57 +0100
commit6fa617524a6d0a2bc988e2dc70e8d719d1b9c282 (patch)
treeddfabea02cf1692a1430c22f41fab866dbacd5db
parentc3de85efb9f354907a6c74889d15dacd0fa1eda7 (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.cpp2
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp21
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"