aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/util
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@qt.io>2018-09-18 13:16:04 +0200
committerErik Verbruggen <erik.verbruggen@qt.io>2018-09-24 11:38:51 +0000
commit92b2a4f58db9d9ba2ba7428ff017521114c6371e (patch)
tree01b68bedd0c22850b184124f80f7cfc0f614e15f /src/qml/util
parenteaf70aee7f64a44a705f800367dce58f15632275 (diff)
Limit the repeater model size for integer models
Otherwise you might be able to put INT_MAX in, which would cause problems with things like memory allocations. Task-number: QTBUG-54752 Change-Id: I758d04af65049181c0c741ff42e92a6450963201 Reviewed-by: Michael Brasser <michael.brasser@live.com>
Diffstat (limited to 'src/qml/util')
-rw-r--r--src/qml/util/qqmllistaccessor.cpp21
1 files changed, 20 insertions, 1 deletions
diff --git a/src/qml/util/qqmllistaccessor.cpp b/src/qml/util/qqmllistaccessor.cpp
index ad55519ad3..46a11e2bc2 100644
--- a/src/qml/util/qqmllistaccessor.cpp
+++ b/src/qml/util/qqmllistaccessor.cpp
@@ -81,7 +81,26 @@ void QQmlListAccessor::setList(const QVariant &v, QQmlEngine *engine)
} else if (d.userType() == QMetaType::QVariantList) {
m_type = VariantList;
} else if (d.canConvert(QVariant::Int)) {
- m_type = Integer;
+ // Here we have to check for an upper limit, because down the line code might (well, will)
+ // allocate memory depending on the number of elements. The upper limit cannot be INT_MAX:
+ // QVector<QPointer<QQuickItem>> something;
+ // something.resize(count());
+ // (See e.g. QQuickRepeater::regenerate())
+ // This will allocate data along the lines of:
+ // sizeof(QPointer<QQuickItem>) * count() + QVector::headerSize
+ // So, doing an approximate round-down-to-nice-number, we get:
+ const int upperLimit = 100 * 1000 * 1000;
+
+ int i = v.toInt();
+ if (i < 0) {
+ qWarning("Model size of %d is less than 0", i);
+ m_type = Invalid;
+ } else if (i > upperLimit) {
+ qWarning("Model size of %d is bigger than the upper limit %d", i, upperLimit);
+ m_type = Invalid;
+ } else {
+ m_type = Integer;
+ }
} else if ((!enginePrivate && QQmlMetaType::isQObject(d.userType())) ||
(enginePrivate && enginePrivate->isQObject(d.userType()))) {
QObject *data = enginePrivate?enginePrivate->toQObject(d):QQmlMetaType::toQObject(d);