aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Watson <glenn.watson@nokia.com>2012-03-09 09:19:35 +1000
committerQt by Nokia <qt-info@nokia.com>2012-03-09 09:56:25 +0100
commit88a6f771f203814e118f71196c800c93ee769055 (patch)
tree338a91956273422f8d4a2cf9513fc8a15c36d3a2
parent2ecf1f5d8ae37bdb4624bd1e3888a65ec357f7b3 (diff)
Fix crash in listmodel when data is assigned incorrectly.
If a listmodel with static role types is created, it would crash if a role was assigned a value type such as string, and then subsequently assigned an array (sub list) value from a dynamic meta object (created when using get() from JS). Change-Id: Ibfd0b0b40be13b04103b49462cfae42a5c9f9fb9 Reviewed-by: Martin Jones <martin.jones@nokia.com>
-rw-r--r--src/qml/qml/qquicklistmodel.cpp18
-rw-r--r--tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp14
2 files changed, 25 insertions, 7 deletions
diff --git a/src/qml/qml/qquicklistmodel.cpp b/src/qml/qml/qquicklistmodel.cpp
index 30c4f5d1d1..48187ca067 100644
--- a/src/qml/qml/qquicklistmodel.cpp
+++ b/src/qml/qml/qquicklistmodel.cpp
@@ -1110,14 +1110,18 @@ int ListElement::setJsProperty(const ListLayout::Role &role, v8::Handle<v8::Valu
} else if (d->IsNumber()) {
roleIndex = setDoubleProperty(role, d->NumberValue());
} else if (d->IsArray()) {
- ListModel *subModel = new ListModel(role.subLayout, 0, -1);
- v8::Handle<v8::Array> subArray = v8::Handle<v8::Array>::Cast(d);
- int arrayLength = subArray->Length();
- for (int j=0 ; j < arrayLength ; ++j) {
- v8::Handle<v8::Object> subObject = subArray->Get(j)->ToObject();
- subModel->append(subObject, eng);
+ if (role.type == ListLayout::Role::List) {
+ ListModel *subModel = new ListModel(role.subLayout, 0, -1);
+ v8::Handle<v8::Array> subArray = v8::Handle<v8::Array>::Cast(d);
+ int arrayLength = subArray->Length();
+ for (int j=0 ; j < arrayLength ; ++j) {
+ v8::Handle<v8::Object> subObject = subArray->Get(j)->ToObject();
+ subModel->append(subObject, eng);
+ }
+ roleIndex = setListProperty(role, subModel);
+ } else {
+ qmlInfo(0) << QString::fromLatin1("Can't assign to existing role '%1' of different type [%2 -> %3]").arg(role.name).arg(roleTypeName(role.type)).arg(roleTypeName(ListLayout::Role::List));
}
- roleIndex = setListProperty(role, subModel);
} else if (d->IsBoolean()) {
roleIndex = setBoolProperty(role, d->BooleanValue());
} else if (d->IsObject()) {
diff --git a/tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp b/tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp
index 3fcce60bfb..69a8d2ecd8 100644
--- a/tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp
+++ b/tests/auto/qml/qquicklistmodel/tst_qquicklistmodel.cpp
@@ -139,6 +139,7 @@ private slots:
void role_mode();
void dynamic_role();
void dynamic_role_data();
+ void string_to_list_crash();
};
bool tst_qquicklistmodel::compareVariantList(const QVariantList &testList, QVariant object)
@@ -1627,6 +1628,19 @@ void tst_qquicklistmodel::dynamic_role()
qApp->processEvents();
}
+void tst_qquicklistmodel::string_to_list_crash()
+{
+ QQmlEngine engine;
+ QQuickListModel model;
+ QQmlEngine::setContextForObject(&model,engine.rootContext());
+ engine.rootContext()->setContextObject(&model);
+ QString script = QLatin1String("{append({'a':'data'});get(0).a = [{'x':123}]}");
+ QTest::ignoreMessage(QtWarningMsg, "<Unknown File>: Can't assign to existing role 'a' of different type [String -> List]");
+ QQmlExpression e(engine.rootContext(), &model, script);
+ // Don't crash!
+ e.evaluate();
+}
+
QTEST_MAIN(tst_qquicklistmodel)
#include "tst_qquicklistmodel.moc"