diff options
author | Erik Verbruggen <erik.verbruggen@qt.io> | 2018-09-18 13:16:04 +0200 |
---|---|---|
committer | Erik Verbruggen <erik.verbruggen@qt.io> | 2018-09-24 11:38:51 +0000 |
commit | 92b2a4f58db9d9ba2ba7428ff017521114c6371e (patch) | |
tree | 01b68bedd0c22850b184124f80f7cfc0f614e15f /src/qml/util | |
parent | eaf70aee7f64a44a705f800367dce58f15632275 (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.cpp | 21 |
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); |