summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.qmake.conf2
-rw-r--r--src/webchannel/qmetaobjectpublisher.cpp9
-rw-r--r--src/webchannel/qwebchannel.js2
-rw-r--r--tests/auto/webchannel/tst_webchannel.cpp56
-rw-r--r--tests/auto/webchannel/tst_webchannel.h20
5 files changed, 84 insertions, 5 deletions
diff --git a/.qmake.conf b/.qmake.conf
index 75ecd52..76d721c 100644
--- a/.qmake.conf
+++ b/.qmake.conf
@@ -1,4 +1,4 @@
load(qt_build_config)
CONFIG += qt_example_installs warning_clean
-MODULE_VERSION = 5.5.1
+MODULE_VERSION = 5.6.0
diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp
index 0cad569..42c95d2 100644
--- a/src/webchannel/qmetaobjectpublisher.cpp
+++ b/src/webchannel/qmetaobjectpublisher.cpp
@@ -449,16 +449,18 @@ QJsonValue QMetaObjectPublisher::wrapResult(const QVariant &result, QWebChannelA
{
if (QObject *object = result.value<QObject *>()) {
QString id = registeredObjectIds.value(object);
+
QJsonObject classInfo;
if (id.isEmpty()) {
// neither registered, nor wrapped, do so now
id = QUuid::createUuid().toString();
- Q_ASSERT(!registeredObjects.contains(id));
+ // store ID before the call to classInfoForObject()
+ // in case of self-contained objects it avoids
+ // infinite loops
+ registeredObjectIds[object] = id;
classInfo = classInfoForObject(object, transport);
- registeredObjectIds[object] = id;
-
ObjectInfo oi(object, classInfo);
if (transport) {
oi.transports.append(transport);
@@ -485,6 +487,7 @@ QJsonValue QMetaObjectPublisher::wrapResult(const QVariant &result, QWebChannelA
objectInfo[KEY_ID] = id;
if (!classInfo.isEmpty())
objectInfo[KEY_DATA] = classInfo;
+
return objectInfo;
} else if (result.canConvert<QJSValue>()) {
// Workaround for keeping QJSValues from QVariant.
diff --git a/src/webchannel/qwebchannel.js b/src/webchannel/qwebchannel.js
index c270a95..f114e77 100644
--- a/src/webchannel/qwebchannel.js
+++ b/src/webchannel/qwebchannel.js
@@ -193,7 +193,7 @@ function QObject(name, data, webChannel)
}
if (!response
|| !response["__QObject*__"]
- || response["id"] === undefined) {
+ || response.id === undefined) {
return response;
}
diff --git a/tests/auto/webchannel/tst_webchannel.cpp b/tests/auto/webchannel/tst_webchannel.cpp
index 55fd2d9..e36a1b3 100644
--- a/tests/auto/webchannel/tst_webchannel.cpp
+++ b/tests/auto/webchannel/tst_webchannel.cpp
@@ -148,6 +148,12 @@ void TestWebChannel::testInfoForObject()
}
{
QJsonArray method;
+ method.append(QStringLiteral("setObjectProperty"));
+ method.append(obj.metaObject()->indexOfMethod("setObjectProperty(QObject*)"));
+ expected.append(method);
+ }
+ {
+ QJsonArray method;
method.append(QStringLiteral("method1"));
method.append(obj.metaObject()->indexOfMethod("method1()"));
expected.append(method);
@@ -230,6 +236,19 @@ void TestWebChannel::testInfoForObject()
property.append(obj.bar());
expected.append(property);
}
+ {
+ QJsonArray property;
+ property.append(obj.metaObject()->indexOfProperty("objectProperty"));
+ property.append(QStringLiteral("objectProperty"));
+ {
+ QJsonArray signal;
+ signal.append(1);
+ signal.append(obj.metaObject()->indexOfMethod("objectPropertyChanged()"));
+ property.append(signal);
+ }
+ property.append(QJsonValue::fromVariant(QVariant::fromValue(obj.objectProperty())));
+ expected.append(property);
+ }
QCOMPARE(info["properties"].toArray(), expected);
}
}
@@ -270,6 +289,43 @@ void TestWebChannel::testDisconnect()
m_dummyTransport->emitMessageReceived(QJsonObject());
}
+void TestWebChannel::testWrapRegisteredObject()
+{
+ QWebChannel channel;
+ TestObject obj;
+ obj.setObjectName("myTestObject");
+
+ channel.registerObject(obj.objectName(), &obj);
+ channel.connectTo(m_dummyTransport);
+ channel.d_func()->publisher->initializeClient(m_dummyTransport);
+
+ QJsonObject objectInfo = channel.d_func()->publisher->wrapResult(QVariant::fromValue(&obj), m_dummyTransport).toObject();
+
+ QCOMPARE(2, objectInfo.length());
+ QVERIFY(objectInfo.contains("id"));
+ QVERIFY(objectInfo.contains("__QObject*__"));
+ QVERIFY(objectInfo.value("__QObject*__").isBool() && objectInfo.value("__QObject*__").toBool());
+
+ QString returnedId = objectInfo.value("id").toString();
+
+ QCOMPARE(&obj, channel.d_func()->publisher->registeredObjects.value(obj.objectName()));
+ QCOMPARE(obj.objectName(), channel.d_func()->publisher->registeredObjectIds.value(&obj));
+ QCOMPARE(obj.objectName(), returnedId);
+}
+
+void TestWebChannel::testInfiniteRecursion()
+{
+ QWebChannel channel;
+ TestObject obj;
+ obj.setObjectProperty(&obj);
+ obj.setObjectName("myTestObject");
+
+ channel.connectTo(m_dummyTransport);
+ channel.d_func()->publisher->initializeClient(m_dummyTransport);
+
+ QJsonObject objectInfo = channel.d_func()->publisher->wrapResult(QVariant::fromValue(&obj), m_dummyTransport).toObject();
+}
+
static QHash<QString, QObject*> createObjects(QObject *parent)
{
const int num = 100;
diff --git a/tests/auto/webchannel/tst_webchannel.h b/tests/auto/webchannel/tst_webchannel.h
index 7b9a1e3..649e61f 100644
--- a/tests/auto/webchannel/tst_webchannel.h
+++ b/tests/auto/webchannel/tst_webchannel.h
@@ -69,9 +69,12 @@ class TestObject : public QObject
Q_PROPERTY(Foo foo READ foo CONSTANT)
Q_PROPERTY(int asdf READ asdf NOTIFY asdfChanged)
Q_PROPERTY(QString bar READ bar NOTIFY theBarHasChanged)
+ Q_PROPERTY(QObject * objectProperty READ objectProperty WRITE setObjectProperty NOTIFY objectPropertyChanged)
+
public:
explicit TestObject(QObject *parent = 0)
: QObject(parent)
+ , mObjectProperty(0)
{ }
enum Foo {
@@ -83,6 +86,11 @@ public:
int asdf() const {return 42;}
QString bar() const {return QString();}
+ QObject *objectProperty() const
+ {
+ return mObjectProperty;
+ }
+
Q_INVOKABLE void method1() {}
protected:
@@ -96,16 +104,26 @@ signals:
void sig2(const QString&);
void asdfChanged();
void theBarHasChanged();
+ void objectPropertyChanged();
public slots:
void slot1() {}
void slot2(const QString&) {}
+ void setObjectProperty(QObject *object)
+ {
+ mObjectProperty = object;
+ emit objectPropertyChanged();
+ }
+
protected slots:
void slot3() {}
private slots:
void slot4() {}
+
+public:
+ QObject *mObjectProperty;
};
class BenchObject : public QObject
@@ -218,6 +236,8 @@ private slots:
void testInfoForObject();
void testInvokeMethodConversion();
void testDisconnect();
+ void testWrapRegisteredObject();
+ void testInfiniteRecursion();
void benchClassInfo();
void benchInitializeClients();