Previously, JS Objects would be converted to a QVariantMap where
each value in the map was a QVariant from toVariant(propertyValue).
Unfortunately, this would result in a crash if the object had a
reference to another object which had a reference to the original
object, due to the circular reference.
This commit changes the conversion code to use
QV8Engine::variantMapFromJS() instead, which avoids cyclic references.
Task-number: QTBUG-21626
Change-Id: I129048c8704ae0d1095a02d0ce4c0fe5850b1b20
Reviewed-on: http://codereview.qt-project.org/5490
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Aaron Kennedy <aaron.kennedy@nokia.com>
int length = properties->Length();
if (length == 0)
return QVariant();
-
- QVariantMap map;
- for (int ii = 0; ii < length; ++ii) {
- v8::Handle<v8::Value> property = properties->Get(ii);
- map.insert(toString(property), toVariant(object->Get(property), -1));
- }
- return map;
+ return variantMapFromJS(object);
}
return QVariant();
--- /dev/null
+import QtQuick 2.0
+
+Rectangle {
+ width: 360
+ height: 360
+
+ function circularObject() {
+ var a = {}
+ var b = {}
+
+ a.test = 100;
+ a.c = b;
+ b.c = a;
+ return a;
+ }
+}
void propertyChangeSlots();
void elementAssign();
void objectPassThroughSignals();
+ void objectConversion();
void booleanConversion();
void handleReferenceManagement();
void stringArg();
delete object;
}
+// QTBUG-21626
+void tst_qdeclarativeecmascript::objectConversion()
+{
+ QDeclarativeComponent component(&engine, TEST_FILE("objectConversion.qml"));
+
+ QObject *object = component.create();
+ QVERIFY(object != 0);
+ QVariant retn;
+ QMetaObject::invokeMethod(object, "circularObject", Q_RETURN_ARG(QVariant, retn));
+ QCOMPARE(retn.value<QVariantMap>().value("test"), QVariant(100));
+
+ delete object;
+}
+
+
// QTBUG-20242
void tst_qdeclarativeecmascript::booleanConversion()
{