From: Chris Adams Date: Mon, 26 Sep 2011 04:25:36 +0000 (+1000) Subject: Modify JS Object to QVariant conversion X-Git-Url: http://git.silmor.de/gitweb/?a=commitdiff_plain;h=20fb62f6040ad8415828092a2b09bd374433505f;p=konrad%2Fqtdeclarative.git Modify JS Object to QVariant conversion 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 Reviewed-by: Aaron Kennedy --- diff --git a/src/declarative/qml/v8/qv8engine.cpp b/src/declarative/qml/v8/qv8engine.cpp index 2108480..33c87b7 100644 --- a/src/declarative/qml/v8/qv8engine.cpp +++ b/src/declarative/qml/v8/qv8engine.cpp @@ -460,13 +460,7 @@ QVariant QV8Engine::toBasicVariant(v8::Handle value) int length = properties->Length(); if (length == 0) return QVariant(); - - QVariantMap map; - for (int ii = 0; ii < length; ++ii) { - v8::Handle property = properties->Get(ii); - map.insert(toString(property), toVariant(object->Get(property), -1)); - } - return map; + return variantMapFromJS(object); } return QVariant(); diff --git a/tests/auto/declarative/qdeclarativeecmascript/data/objectConversion.qml b/tests/auto/declarative/qdeclarativeecmascript/data/objectConversion.qml new file mode 100644 index 0000000..67fc342 --- /dev/null +++ b/tests/auto/declarative/qdeclarativeecmascript/data/objectConversion.qml @@ -0,0 +1,16 @@ +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; + } +} diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 537965c..9200e0f 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -152,6 +152,7 @@ private slots: void propertyChangeSlots(); void elementAssign(); void objectPassThroughSignals(); + void objectConversion(); void booleanConversion(); void handleReferenceManagement(); void stringArg(); @@ -3314,6 +3315,21 @@ void tst_qdeclarativeecmascript::objectPassThroughSignals() 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().value("test"), QVariant(100)); + + delete object; +} + + // QTBUG-20242 void tst_qdeclarativeecmascript::booleanConversion() {