QDBusSignature: accept empty strings as valid

QDBusSignature holds a D-Bus value of type SIGNATURE, which is zero or
more signatures, not one or more. This changes the default constructor
to create a valid signature, which we denote by not being a null
QString. That means we need to use something other than the default
constructor in our tests for attempting to pass invalid signatures.

[ChangeLog][QtDBus][QDBusSignature] Fixed a bug that caused the class
not to accept an empty string as a valid D-Bus SIGNATURE value.

Fixes: QTBUG-124919
Pick-to: 6.5
Change-Id: I262c3499666e4f4fbcfbfffd17cb3793dcf2eae3
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit ed6d1fa71a79a70b7e6a20fbbc737ed9f6c287b1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Thiago Macieira 2024-04-30 17:59:51 -07:00 committed by Qt Cherry-pick Bot
parent 4dfb99fcb2
commit 12ae2e8075
6 changed files with 25 additions and 11 deletions

View File

@ -25,6 +25,8 @@ void QDBusSignature::doCheck()
if (!QDBusUtil::isValidSignature(m_signature)) {
qWarning("QDBusSignature: invalid signature \"%s\"", qPrintable(m_signature));
m_signature.clear();
} else if (m_signature.isEmpty()) {
m_signature.detach(); // we need it to not be null
}
}

View File

@ -74,7 +74,10 @@ class Q_DBUS_EXPORT QDBusSignature
{
QString m_signature;
public:
QDBusSignature() noexcept : m_signature() {}
QDBusSignature() noexcept
{
m_signature.detach(); // mark non-null (empty signatures are valid)
}
// compiler-generated copy/move constructor/assignment operators are ok!
// compiler-generated destructor is ok!

View File

@ -120,7 +120,7 @@ inline void QDBusMarshaller::append(const QDBusObjectPath &arg)
inline void QDBusMarshaller::append(const QDBusSignature &arg)
{
QByteArray data = arg.signature().toUtf8();
if (!ba && data.isEmpty()) {
if (!ba && data.isNull()) {
error("Invalid signature passed in arguments"_L1);
} else {
const char *cdata = data.constData();

View File

@ -512,14 +512,14 @@ namespace QDBusUtil
bool isValidSignature(const QString &signature)
{
QByteArray ba = signature.toLatin1();
const char *data = ba.constData();
while (true) {
const char *data = ba.constBegin();
const char *end = ba.constEnd();
while (data != end) {
data = validateSingleType(data);
if (!data)
return false;
if (*data == '\0')
return true;
}
return true;
}
/*!

View File

@ -161,7 +161,9 @@ void basicStringTypes_data()
{
QTest::newRow("string") << QVariant("ping") << "s" << "\"ping\"";
QTest::newRow("objectpath") << QVariant::fromValue(QDBusObjectPath("/org/kde")) << "o" << "[ObjectPath: /org/kde]";
QTest::newRow("emptysignature") << QVariant::fromValue(QDBusSignature(QString())) << "g" << "[Signature: ]";
QTest::newRow("signature") << QVariant::fromValue(QDBusSignature("g")) << "g" << "[Signature: g]";
QTest::newRow("multisignature") << QVariant::fromValue(QDBusSignature("bit")) << "g" << "[Signature: bit]";
QTest::newRow("emptystring") << QVariant("") << "s" << "\"\"";
QTest::newRow("nullstring") << QVariant(QString()) << "s" << "\"\"";
}
@ -907,7 +909,7 @@ void tst_QDBusMarshall::sendSignalErrors()
QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal to service \"\" path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid object path passed in arguments");
QVERIFY(!con.send(msg));
QDBusSignature sig;
QDBusSignature sig(QChar(0));
msg.setArguments(QVariantList() << QVariant::fromValue(sig));
QTest::ignoreMessage(QtWarningMsg, "QDBusConnection: error: could not send signal to service \"\" path \"/foo\" interface \"local.interfaceName\" member \"signalName\": Marshalling failed: Invalid signature passed in arguments");
QVERIFY(!con.send(msg));
@ -992,7 +994,7 @@ void tst_QDBusMarshall::sendCallErrors_data()
<< "";
QTest::newRow("invalid-signature-arg") << serviceName << objectPath << interfaceName << "ping"
<< (QVariantList() << QVariant::fromValue(QDBusSignature()))
<< (QVariantList() << QVariant::fromValue(QDBusSignature(QChar(0))))
<< "org.freedesktop.DBus.Error.Failed"
<< "Marshalling failed: Invalid signature passed in arguments"
<< "";

View File

@ -206,6 +206,7 @@ void tst_QDBusType::isValidBasicType()
void tst_QDBusType::isValidSingleSignature_data()
{
addColumns();
QTest::newRow("empty") << "" << false;
addSingleSignatures();
addNakedDictEntry();
}
@ -222,6 +223,7 @@ void tst_QDBusType::isValidSingleSignature()
void tst_QDBusType::isValidArray_data()
{
addColumns();
QTest::newRow("empty") << "" << false;
addSingleSignatures();
}
@ -241,7 +243,10 @@ void tst_QDBusType::isValidArray()
void tst_QDBusType::isValidSignature_data()
{
isValidSingleSignature_data();
addColumns();
QTest::newRow("empty") << "" << true;
addSingleSignatures();
addNakedDictEntry();
}
void tst_QDBusType::isValidSignature()
@ -250,8 +255,10 @@ void tst_QDBusType::isValidSignature()
QFETCH(bool, result);
data.append(data);
if (data.at(0).unicode())
QCOMPARE(bool(q_dbus_signature_validate(data.toLatin1(), 0)), result);
if (!data.isEmpty() && data.at(0).unicode()) {
// libdbus-1 API can't deal with string containing NULs
QCOMPARE(bool(q_dbus_signature_validate(data.toLatin1(), nullptr)), result);
}
QCOMPARE(QDBusUtil::isValidSignature(data), result);
}