aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@qt.io>2018-07-05 17:05:06 +0200
committerUlf Hermann <ulf.hermann@qt.io>2018-07-10 07:42:27 +0000
commit4c3784f9841e83229c704813e7640b0f5df2febb (patch)
tree765a594ec6cf75a673fb48deed0130327e2e9492 /src
parent77fa37ff3db59eef589fc2f89a26c1af568b3d76 (diff)
QML Debugger: Check in time if values can be saved to QDataStream
If you feed something non-saveable to operator<<() the application will crash. Task-number: QTBUG-69316 Change-Id: I9fe5f83a9eb49e5bde3002c0a5dda4206470c644 Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp43
1 files changed, 34 insertions, 9 deletions
diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
index 17bae6d695..4c104f01de 100644
--- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
+++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp
@@ -68,6 +68,37 @@ QT_BEGIN_NAMESPACE
using QQmlDebugPacket = QVersionedPacket<QQmlDebugConnector>;
+class NullDevice : public QIODevice
+{
+public:
+ NullDevice() { open(QIODevice::ReadWrite); }
+
+protected:
+ qint64 readData(char *data, qint64 maxlen) final;
+ qint64 writeData(const char *data, qint64 len) final;
+};
+
+qint64 NullDevice::readData(char *data, qint64 maxlen)
+{
+ Q_UNUSED(data);
+ return maxlen;
+}
+
+qint64 NullDevice::writeData(const char *data, qint64 len)
+{
+ Q_UNUSED(data);
+ return len;
+}
+
+// check whether the data can be saved
+// (otherwise we assert in QVariant::operator<< when actually saving it)
+static bool isSaveable(const QVariant &value)
+{
+ NullDevice nullDevice;
+ QDataStream fakeStream(&nullDevice);
+ return QMetaType::save(fakeStream, static_cast<int>(value.type()), value.constData());
+}
+
QQmlEngineDebugServiceImpl::QQmlEngineDebugServiceImpl(QObject *parent) :
QQmlEngineDebugService(2, parent), m_watch(new QQmlWatcher(this)), m_statesDelegate(nullptr)
{
@@ -106,13 +137,7 @@ QDataStream &operator<<(QDataStream &ds,
const QQmlEngineDebugServiceImpl::QQmlObjectProperty &data)
{
ds << (int)data.type << data.name;
- // check first whether the data can be saved
- // (otherwise we assert in QVariant::operator<<)
- QQmlDebugPacket fakeStream;
- if (QMetaType::save(fakeStream, data.value.type(), data.value.constData()))
- ds << data.value;
- else
- ds << QVariant();
+ ds << (isSaveable(data.value) ? data.value : QVariant());
ds << data.valueTypeName << data.binding << data.hasNotifySignal;
return ds;
}
@@ -247,8 +272,8 @@ QVariant QQmlEngineDebugServiceImpl::valueContents(QVariant value) const
}
}
- // We expect all QML value types to either have a toString() method or stream operators
- return value;
+ if (isSaveable(value))
+ return value;
}
}