|
1 | | -// SPDX-FileCopyrightText: 2016 - 2023 UnionTech Software Technology Co., Ltd. |
| 1 | +// SPDX-FileCopyrightText: 2016 - 2026 UnionTech Software Technology Co., Ltd. |
2 | 2 | // |
3 | 3 | // SPDX-License-Identifier: LGPL-3.0-or-later |
4 | 4 |
|
@@ -54,37 +54,58 @@ void SecureErase(T &obj) |
54 | 54 | } |
55 | 55 | } |
56 | 56 |
|
57 | | -inline QString escapeToObjectPath(const QString &str) |
| 57 | +inline QString escapeToObjectPath(const QByteArray &str) noexcept |
58 | 58 | { |
59 | 59 | if (str.isEmpty()) { |
60 | | - return "_"; |
| 60 | + return QStringLiteral("_"); |
61 | 61 | } |
62 | 62 |
|
63 | | - auto ret = str; |
64 | | - QRegularExpression re{R"([^a-zA-Z0-9])"}; |
65 | | - auto matcher = re.globalMatch(ret); |
66 | | - while (matcher.hasNext()) { |
67 | | - auto replaceList = matcher.next().capturedTexts(); |
68 | | - replaceList.removeDuplicates(); |
69 | | - for (const auto &c : replaceList) { |
70 | | - auto hexStr = QString::number(static_cast<uint>(c.front().toLatin1()), 16); |
71 | | - ret.replace(c, QString{R"(_%1)"}.arg(hexStr)); |
| 63 | + QString ret; |
| 64 | + ret.reserve(str.size() * 3); |
| 65 | + |
| 66 | + for (qsizetype i = 0; i < str.size(); ++i) { |
| 67 | + auto byte = static_cast<unsigned char>(str.at(i)); |
| 68 | + if (std::isalnum(byte) != 0 || byte == '/') { |
| 69 | + ret.append(QChar::fromLatin1(byte)); |
| 70 | + } else { |
| 71 | + // TODO: a valid dbus object path component only allows "[A-Z][a-z][0-9]_" |
| 72 | + // for compatibility with existing applications, we escape all unicode to avoid breakage |
| 73 | + // but we should consider to drop this compatibility hack in the future. |
| 74 | + ret.append(u'_'); |
| 75 | + ret.append(QString::number(byte, 16).rightJustified(2, u'0').toLower()); |
72 | 76 | } |
73 | 77 | } |
| 78 | + |
| 79 | + ret.shrink_to_fit(); |
74 | 80 | return ret; |
75 | 81 | } |
76 | 82 |
|
77 | | -inline QString unescapeFromObjectPath(const QString &str) |
| 83 | +inline QString escapeToObjectPath(const QString &str) noexcept |
| 84 | +{ |
| 85 | + return escapeToObjectPath(str.toUtf8()); |
| 86 | +} |
| 87 | + |
| 88 | +inline QString unescapeFromObjectPath(const QString &str) noexcept |
78 | 89 | { |
79 | | - auto ret = str; |
80 | | - for (int i = 0; i < str.size(); ++i) { |
81 | | - if (str[i] == '_' && i + 2 < str.size()) { |
82 | | - auto hexStr = str.mid(i + 1, 2); |
83 | | - ret.replace(QString{"_%1"}.arg(hexStr), QChar::fromLatin1(hexStr.toUInt(nullptr, 16))); |
84 | | - i += 2; |
| 90 | + QByteArray ret; |
| 91 | + ret.reserve(str.length()); |
| 92 | + |
| 93 | + for (qsizetype i = 0; i < str.length();) { |
| 94 | + if (i <= str.length() - 3 && str.at(i) == u'_') { |
| 95 | + bool ok{false}; |
| 96 | + auto byte = static_cast<unsigned char>(str.mid(i + 1, 2).toUShort(&ok, 16)); |
| 97 | + if (ok) { |
| 98 | + ret.append(static_cast<char>(byte)); |
| 99 | + i += 3; |
| 100 | + continue; |
| 101 | + } |
85 | 102 | } |
| 103 | + |
| 104 | + ret.append(str.at(i).toLatin1()); |
| 105 | + ++i; |
86 | 106 | } |
87 | | - return ret; |
| 107 | + |
| 108 | + return QString::fromUtf8(ret); |
88 | 109 | } |
89 | 110 |
|
90 | 111 | inline QString getAppIdFromAbsolutePath(const QString &path) |
|
0 commit comments