Skip to content

Commit

Permalink
Modify JS Object to QVariant conversion
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Chris Adams authored and Qt by Nokia committed Sep 30, 2011
1 parent 54c1fa8 commit 20fb62f
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 7 deletions.
8 changes: 1 addition & 7 deletions src/declarative/qml/v8/qv8engine.cpp
Expand Up @@ -460,13 +460,7 @@ QVariant QV8Engine::toBasicVariant(v8::Handle<v8::Value> value)
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();
Expand Down
@@ -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;
}
}
Expand Up @@ -152,6 +152,7 @@ private slots:
void propertyChangeSlots();
void elementAssign();
void objectPassThroughSignals();
void objectConversion();
void booleanConversion();
void handleReferenceManagement();
void stringArg();
Expand Down Expand Up @@ -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<QVariantMap>().value("test"), QVariant(100));

delete object;
}


// QTBUG-20242
void tst_qdeclarativeecmascript::booleanConversion()
{
Expand Down

0 comments on commit 20fb62f

Please sign in to comment.