aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArno Rehn <a.rehn@menlosystems.com>2019-07-11 20:51:07 +0200
committerArno Rehn <a.rehn@menlosystems.com>2019-07-26 15:47:47 +0200
commit29496e3f08e20398e253e6d32bb95879a1a68978 (patch)
tree2896ce0f5f0beaa694d70342646143a1e5f69063
parent25fb211a32890a1bdd2b28b9727f6806a88d221c (diff)
Correctly link transports to implicitly wrapped objects
When an object is wrapped as consequence of a property update or signal emission, wrapResult() assigns it the parent object's list of transports. It didn't, however, establish the reverse relation, i.e from transport to object. This resulted in dangling pointers after client disconnects and subsequent crashes. This patch fixes the bug. Change-Id: I5d20269c453902bf2883dfcab1f3ab5d0757c2cd Reviewed-by: Frederik Gladhorn <frederik.gladhorn@qt.io>
-rw-r--r--src/webchannel/qmetaobjectpublisher.cpp6
-rw-r--r--tests/auto/webchannel/tst_webchannel.cpp30
-rw-r--r--tests/auto/webchannel/tst_webchannel.h1
3 files changed, 36 insertions, 1 deletions
diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp
index 102cbda..e23921d 100644
--- a/src/webchannel/qmetaobjectpublisher.cpp
+++ b/src/webchannel/qmetaobjectpublisher.cpp
@@ -739,15 +739,19 @@ QJsonValue QMetaObjectPublisher::wrapResult(const QVariant &result, QWebChannelA
ObjectInfo oi(object);
if (transport) {
oi.transports.append(transport);
+ transportedWrappedObjects.insert(transport, id);
} else {
// use the transports from the parent object
oi.transports = wrappedObjects.value(parentObjectId).transports;
// or fallback to all transports if the parent is not wrapped
if (oi.transports.isEmpty())
oi.transports = webChannel->d_func()->transports;
+
+ for (auto transport : qAsConst(oi.transports)) {
+ transportedWrappedObjects.insert(transport, id);
+ }
}
wrappedObjects.insert(id, oi);
- transportedWrappedObjects.insert(transport, id);
initializePropertyUpdates(object, classInfo);
} else if (wrappedObjects.contains(id)) {
diff --git a/tests/auto/webchannel/tst_webchannel.cpp b/tests/auto/webchannel/tst_webchannel.cpp
index ffaebba..4a66bdd 100644
--- a/tests/auto/webchannel/tst_webchannel.cpp
+++ b/tests/auto/webchannel/tst_webchannel.cpp
@@ -757,6 +757,36 @@ void TestWebChannel::testUnwrapObject()
}
}
+void TestWebChannel::testTransportWrapObjectProperties()
+{
+ QWebChannel channel;
+
+ TestObject obj;
+ obj.setObjectName("testObject");
+ channel.registerObject(obj.objectName(), &obj);
+
+ DummyTransport *dummyTransport = new DummyTransport(this);
+ channel.connectTo(dummyTransport);
+ channel.d_func()->publisher->initializeClient(dummyTransport);
+ channel.d_func()->publisher->setClientIsIdle(true);
+
+ QCOMPARE(channel.d_func()->publisher->transportedWrappedObjects.size(), 0);
+
+ QObject objPropObject;
+ objPropObject.setObjectName("foobar");
+
+ obj.setObjectProperty(&objPropObject);
+
+ channel.d_func()->publisher->sendPendingPropertyUpdates();
+
+ QCOMPARE(channel.d_func()->publisher->wrappedObjects.size(), 1);
+ const QString wrappedObjId = channel.d_func()->publisher->wrappedObjects.keys()[0];
+
+ QCOMPARE(channel.d_func()->publisher->transportedWrappedObjects.size(), 1);
+ QCOMPARE(channel.d_func()->publisher->transportedWrappedObjects.keys()[0], dummyTransport);
+ QCOMPARE(channel.d_func()->publisher->transportedWrappedObjects.values()[0], wrappedObjId);
+}
+
void TestWebChannel::testRemoveUnusedTransports()
{
QWebChannel channel;
diff --git a/tests/auto/webchannel/tst_webchannel.h b/tests/auto/webchannel/tst_webchannel.h
index 8ca1cdd..7cfce06 100644
--- a/tests/auto/webchannel/tst_webchannel.h
+++ b/tests/auto/webchannel/tst_webchannel.h
@@ -327,6 +327,7 @@ private slots:
void testDisconnect();
void testWrapRegisteredObject();
void testUnwrapObject();
+ void testTransportWrapObjectProperties();
void testRemoveUnusedTransports();
void testPassWrappedObjectBack();
void testWrapValues();