aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2020-01-07 10:52:29 +0100
committerUlf Hermann <ulf.hermann@qt.io>2020-01-08 09:28:52 +0100
commit5e9a7246acb44a04c51bf066fc2e24368ca47204 (patch)
tree21e1fd8090500cfd426d16c32aac68ff6ebb28ad
parent5c681f0f0f220c80f412d36a1b644c3eb5e080df (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.cpp8
-rw-r--r--tests/auto/qml/qjsengine/tst_qjsengine.cpp13
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"