diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2020-01-07 10:52:29 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2020-01-08 09:28:52 +0100 |
commit | 5e9a7246acb44a04c51bf066fc2e24368ca47204 (patch) | |
tree | 21e1fd8090500cfd426d16c32aac68ff6ebb28ad | |
parent | 5c681f0f0f220c80f412d36a1b644c3eb5e080df (diff) |
Check stack limit in FunctionPrototype::method_apply()
We could just crash there, assuming unlimited memory, but as this
particular place seems to be a very attractive target for various
mischief, let's just plug it.
Change-Id: I3b0369ceb34dafd12ce8dc1f189fc5f9ee82c169
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
-rw-r--r-- | src/qml/jsruntime/qv4functionobject.cpp | 8 | ||||
-rw-r--r-- | tests/auto/qml/qjsengine/tst_qjsengine.cpp | 13 |
2 files changed, 20 insertions, 1 deletions
diff --git a/src/qml/jsruntime/qv4functionobject.cpp b/src/qml/jsruntime/qv4functionobject.cpp index 6fb7946023..dfef52583e 100644 --- a/src/qml/jsruntime/qv4functionobject.cpp +++ b/src/qml/jsruntime/qv4functionobject.cpp @@ -364,7 +364,13 @@ ReturnedValue FunctionPrototype::method_apply(const QV4::FunctionObject *b, cons if (!arr) return v4->throwTypeError(); - uint len = arr->getLength(); + const qint64 len64 = arr->getLength(); + if (len64 < 0ll || len64 > qint64(std::numeric_limits<int>::max())) + return v4->throwRangeError(QStringLiteral("Invalid array length.")); + if (len64 > qint64(v4->jsStackLimit - v4->jsStackTop)) + return v4->throwRangeError(QStringLiteral("Array too large for apply().")); + + const uint len = uint(len64); Scope scope(v4); Value *arguments = scope.alloc<Scope::Uninitialized>(len); diff --git a/tests/auto/qml/qjsengine/tst_qjsengine.cpp b/tests/auto/qml/qjsengine/tst_qjsengine.cpp index df428d5929..e379cb1f11 100644 --- a/tests/auto/qml/qjsengine/tst_qjsengine.cpp +++ b/tests/auto/qml/qjsengine/tst_qjsengine.cpp @@ -257,6 +257,7 @@ private slots: void compileBrokenRegexp(); void sortNonStringArray(); void iterateInvalidProxy(); + void applyOnHugeArray(); void tostringRecursionCheck(); void arrayIncludesWithLargeArray(); @@ -5094,6 +5095,18 @@ void tst_QJSEngine::iterateInvalidProxy() QCOMPARE(value.toString(), "TypeError: Type error"); } +void tst_QJSEngine::applyOnHugeArray() +{ + QJSEngine engine; + const auto value = engine.evaluate( + "var a = new Array(10);" + "a[536870912] = Function;" + "Function.apply('aaaaaaaa', a);" + ); + QVERIFY(value.isError()); + QCOMPARE(value.toString(), "RangeError: Array too large for apply()."); +} + QTEST_MAIN(tst_QJSEngine) #include "tst_qjsengine.moc" |