summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorSami Rosendahl <ext-sami.1.rosendahl@nokia.com>2012-01-17 11:37:35 (GMT)
committerQt by Nokia <qt-info@nokia.com>2012-01-25 12:29:00 (GMT)
commit03905f771b23b1e6d33e6b42811b8b5e915c9d8f (patch)
treefa1f809131c6318b9ef965c66a08493a888ec6e0 /tests/auto
parentb34d903466a34668973030341e2f12d2b481ed58 (diff)
downloadQt-03905f771b23b1e6d33e6b42811b8b5e915c9d8f.zip
Qt-03905f771b23b1e6d33e6b42811b8b5e915c9d8f.tar.gz
Qt-03905f771b23b1e6d33e6b42811b8b5e915c9d8f.tar.bz2
Fix crash in QDBusDemarshaller basic string-like type extraction
QDBusArgument string extraction operators and QDBusDemarshaller that implements the extraction do not check the type of the extracted value. When extracting string-like basic DBus type that actually is e.g. an integer the string extraction will crash as it blindly attempts to use the integer as a pointer to char. The fix adds DBus type checks to QDBusArgument string type extraction operator implementations. The checks are as permissive as possible provided crashes are avoided. Previously supported functionality of extracting an object path or type signature to a string type is retained. Task-number: QTBUG-22840 Change-Id: Ia27d4f4d461e5c4d3eac52f3cac85d6734f000b3 (From Qt5 commit 8f19f142745f3cb0690dcd51cebc66153e396805) Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp115
1 files changed, 115 insertions, 0 deletions
diff --git a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
index cc5e68d..bf7270e 100644
--- a/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
+++ b/tests/auto/qdbusmarshall/tst_qdbusmarshall.cpp
@@ -96,6 +96,9 @@ private slots:
void demarshallPrimitives_data();
void demarshallPrimitives();
+ void demarshallStrings_data();
+ void demarshallStrings();
+
private:
int fileDescriptorForTest();
@@ -1268,5 +1271,117 @@ void tst_QDBusMarshall::demarshallPrimitives()
}
}
+void tst_QDBusMarshall::demarshallStrings_data()
+{
+ QTest::addColumn<QVariant>("value");
+ QTest::addColumn<char>("targetSig");
+ QTest::addColumn<QVariant>("expectedValue");
+
+ // All primitive types demarshall to null string types
+ typedef QPair<QVariant, char> ValSigPair;
+ const QList<ValSigPair> nullStringTypes
+ = QList<ValSigPair>()
+ << ValSigPair(qVariantFromValue(QString()), 's')
+ << ValSigPair(qVariantFromValue(QDBusObjectPath()), 'o')
+ << ValSigPair(qVariantFromValue(QDBusSignature()), 'g');
+ foreach (ValSigPair valSigPair, nullStringTypes) {
+ QTest::newRow("bool(false)") << QVariant(false) << valSigPair.second << valSigPair.first;
+ QTest::newRow("bool(true)") << QVariant(true) << valSigPair.second << valSigPair.first;
+ QTest::newRow("byte") << qVariantFromValue(uchar(1)) << valSigPair.second << valSigPair.first;
+ QTest::newRow("int16") << qVariantFromValue(short(2)) << valSigPair.second << valSigPair.first;
+ QTest::newRow("uint16") << qVariantFromValue(ushort(3)) << valSigPair.second << valSigPair.first;
+ QTest::newRow("int") << QVariant(1) << valSigPair.second << valSigPair.first;
+ QTest::newRow("uint") << QVariant(2U) << valSigPair.second << valSigPair.first;
+ QTest::newRow("int64") << QVariant(Q_INT64_C(3)) << valSigPair.second << valSigPair.first;
+ QTest::newRow("uint64") << QVariant(Q_UINT64_C(4)) << valSigPair.second << valSigPair.first;
+ QTest::newRow("double") << QVariant(42.5) << valSigPair.second << valSigPair.first;
+ }
+
+ // String types should demarshall to each other. This is a regression test
+ // to check released functionality is maintained even after checks have
+ // been added to string demarshalling
+ QTest::newRow("empty string->invalid objectpath") << QVariant("")
+ << 'o' << qVariantFromValue(QDBusObjectPath());
+ QTest::newRow("null string->invalid objectpath") << QVariant(QString())
+ << 'o' << qVariantFromValue(QDBusObjectPath());
+ QTest::newRow("string->invalid objectpath") << QVariant("invalid objectpath")
+ << 'o' << qVariantFromValue(QDBusObjectPath());
+ QTest::newRow("string->valid objectpath") << QVariant("/org/kde")
+ << 'o' << qVariantFromValue(QDBusObjectPath("/org/kde"));
+
+ QTest::newRow("empty string->invalid signature") << QVariant("")
+ << 'g' << qVariantFromValue(QDBusSignature());
+ QTest::newRow("null string->invalid signature") << QVariant(QString())
+ << 'g' << qVariantFromValue(QDBusSignature());
+ QTest::newRow("string->invalid signature") << QVariant("_invalid signature")
+ << 'g' << qVariantFromValue(QDBusSignature());
+ QTest::newRow("string->valid signature") << QVariant("s")
+ << 'g' << qVariantFromValue(QDBusSignature("s"));
+
+ QTest::newRow("objectpath->string") << qVariantFromValue(QDBusObjectPath("/org/kde"))
+ << 's' << qVariantFromValue(QString("/org/kde"));
+ QTest::newRow("objectpath->invalid signature") << qVariantFromValue(QDBusObjectPath("/org/kde"))
+ << 'g' << qVariantFromValue(QDBusSignature());
+
+ QTest::newRow("signature->string") << qVariantFromValue(QDBusSignature("s"))
+ << 's' << qVariantFromValue(QString("s"));
+ QTest::newRow("signature->invalid objectpath") << qVariantFromValue(QDBusSignature("s"))
+ << 'o' << qVariantFromValue(QDBusObjectPath());
+}
+
+QVariant demarshallAsString(const QDBusArgument& dbusArg, char targetSig)
+{
+ switch (targetSig) {
+ case 's': {
+ QString s;
+ dbusArg >> s;
+ return s;
+ }
+ case 'o': {
+ QDBusObjectPath op;
+ dbusArg >> op;
+ return qVariantFromValue(op);
+ }
+ case 'g' : {
+ QDBusSignature sig;
+ dbusArg >> sig;
+ return qVariantFromValue(sig);
+ }
+ default: {
+ return QVariant();
+ }
+ }
+}
+
+void tst_QDBusMarshall::demarshallStrings()
+{
+ QFETCH(QVariant, value);
+ QFETCH(char, targetSig);
+ QFETCH(QVariant, expectedValue);
+
+ QDBusConnection con = QDBusConnection::sessionBus();
+
+ QVERIFY(con.isConnected());
+
+ QDBusMessage msg = QDBusMessage::createMethodCall(serviceName, objectPath,
+ interfaceName, "ping");
+ QDBusArgument sendArg;
+ sendArg.beginStructure();
+ sendArg.appendVariant(value);
+ sendArg.endStructure();
+ msg.setArguments(QVariantList() << qVariantFromValue(sendArg));
+ QDBusMessage reply = con.call(msg);
+
+ const QDBusArgument receiveArg = qvariant_cast<QDBusArgument>(reply.arguments().at(0));
+ receiveArg.beginStructure();
+
+ QVariant receiveValue = demarshallAsString(receiveArg, targetSig);
+ QVERIFY2(receiveValue.isValid(), "Invalid targetSig in demarshallStrings_data()");
+ QVERIFY(compare(receiveValue, expectedValue));
+
+ receiveArg.endStructure();
+ QVERIFY(receiveArg.atEnd());
+}
+
QTEST_MAIN(tst_QDBusMarshall)
#include "tst_qdbusmarshall.moc"