mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-03-22 14:55:36 +08:00
Fix dbus assert when hostname contains non-Latin characters
This commit is contained in:
@@ -21,27 +21,25 @@ BLACK_DEFINE_VALUEOBJECT_MIXINS(BlackMisc, CIdentifier)
|
||||
//! \private Escape characters not allowed in dbus paths
|
||||
QString toDBusPath(const QString &s)
|
||||
{
|
||||
Q_ASSERT_X(!BlackMisc::containsChar(s, [](QChar c) { return c.unicode() > 0x7f; }), Q_FUNC_INFO, "7-bit ASCII only");
|
||||
return s.toLatin1().toPercentEncoding("/", "-._~", '_');
|
||||
return BlackMisc::utfToPercentEncoding(s, "/", '_');
|
||||
}
|
||||
|
||||
//! \private Escape characters not allowed in dbus path elements
|
||||
QString toDBusPathElement(const QString &s)
|
||||
{
|
||||
Q_ASSERT_X(!BlackMisc::containsChar(s, [](QChar c) { return c.unicode() > 0x7f; }), Q_FUNC_INFO, "7-bit ASCII only");
|
||||
return s.toLatin1().toPercentEncoding({}, "-._~", '_');
|
||||
return BlackMisc::utfToPercentEncoding(s, {}, '_');
|
||||
}
|
||||
|
||||
//! \private Unescape characters not allowed in dbus paths
|
||||
QString fromDBusPath(const QString &s)
|
||||
{
|
||||
return QByteArray::fromPercentEncoding(s.toLatin1(), '_');
|
||||
return BlackMisc::utfFromPercentEncoding(s.toLatin1(), '_');
|
||||
}
|
||||
|
||||
//! \private Unescape characters not allowed in dbus path elements
|
||||
QString fromDBusPathElement(const QString &s)
|
||||
{
|
||||
return QByteArray::fromPercentEncoding(s.toLatin1(), '_');
|
||||
return BlackMisc::utfFromPercentEncoding(s.toLatin1(), '_');
|
||||
}
|
||||
|
||||
//! \private
|
||||
|
||||
@@ -34,6 +34,69 @@ namespace BlackMisc
|
||||
return splitString(s, [](QChar c) { return c == '\n' || c == '\r'; });
|
||||
}
|
||||
|
||||
QByteArray utfToPercentEncoding(const QString& s, const QByteArray &allow, char percent)
|
||||
{
|
||||
QByteArray result;
|
||||
for (const QChar &c : s)
|
||||
{
|
||||
if (const char latin = c.toLatin1())
|
||||
{
|
||||
if ((latin >= 'a' && latin <= 'z') || (latin >= 'A' && latin <= 'Z')
|
||||
|| (latin >= '0' && latin <= '9') || allow.contains(latin))
|
||||
{
|
||||
result += c;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += percent;
|
||||
if (latin < 0x10) { result += '0'; }
|
||||
result += QByteArray::number(static_cast<int>(latin), 16);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result += percent;
|
||||
result += 'x';
|
||||
const ushort unicode = c.unicode();
|
||||
if (unicode < 0x0010) { result += '0'; }
|
||||
if (unicode < 0x0100) { result += '0'; }
|
||||
if (unicode < 0x1000) { result += '0'; }
|
||||
result += QByteArray::number(unicode, 16);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
QString utfFromPercentEncoding(const QByteArray& ba, char percent)
|
||||
{
|
||||
QString result;
|
||||
for (int i = 0; i < ba.size(); ++i)
|
||||
{
|
||||
if (ba[i] == percent)
|
||||
{
|
||||
++i;
|
||||
Q_ASSERT(i < ba.size());
|
||||
if (ba[i] == 'x')
|
||||
{
|
||||
++i;
|
||||
Q_ASSERT(i < ba.size());
|
||||
result += QChar(ba.mid(i, 4).toInt(nullptr, 16));
|
||||
i += 3;
|
||||
}
|
||||
else
|
||||
{
|
||||
result += static_cast<char>(ba.mid(i, 2).toInt(nullptr, 16));
|
||||
++i;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
result += ba[i];
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const QString &boolToOnOff(bool v)
|
||||
{
|
||||
static const QString on("on");
|
||||
|
||||
@@ -126,6 +126,12 @@ namespace BlackMisc
|
||||
//! Split a string into multiple lines. Blank lines are skipped.
|
||||
BLACKMISC_EXPORT QStringList splitLines(const QString &s);
|
||||
|
||||
//! Extended percent encoding supporting UTF-16
|
||||
BLACKMISC_EXPORT QByteArray utfToPercentEncoding(const QString &s, const QByteArray &allow = {}, char percent = '%');
|
||||
|
||||
//! Reverse utfFromPercentEncoding
|
||||
BLACKMISC_EXPORT QString utfFromPercentEncoding(const QByteArray &ba, char percent = '%');
|
||||
|
||||
//! A map converted to string
|
||||
template<class K, class V> QString qmapToString(const QMap<K, V> &map)
|
||||
{
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace BlackMiscTest
|
||||
void CTestIdentifier::dbusObjectPath()
|
||||
{
|
||||
QObject q;
|
||||
q.setObjectName("!@#$%^&*()_+");
|
||||
q.setObjectName(QString::fromUtf16(u"!@#$%^&*()_+\u263a"));
|
||||
CTestIdentifiable id(&q);
|
||||
QString s(id.identifier().toDBusObjectPath());
|
||||
QVERIFY2(id.identifier() == CIdentifier::fromDBusObjectPath(s), "Conversion from dbus object path and back compares equal");
|
||||
|
||||
@@ -129,12 +129,17 @@ namespace BlackMiscTest
|
||||
//! ctor
|
||||
Server()
|
||||
{
|
||||
QObject::connect(&m_process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), [](int code, QProcess::ExitStatus status)
|
||||
{
|
||||
qDebug() << "Server process exited" << (status ? "abnormally" : "normally") << "with exit code" << code;
|
||||
});
|
||||
m_process.start("sharedstatetestserver", QStringList());
|
||||
m_process.waitForStarted();
|
||||
}
|
||||
//! dtor
|
||||
~Server()
|
||||
{
|
||||
m_process.disconnect();
|
||||
m_process.kill();
|
||||
m_process.waitForFinished();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user