1
0
mirror of https://github.com/qt/qtmqtt.git synced 2026-10-25 16:16:26 +00:00

Fix wildcard filter matching

Each sub item in the filter tree needs to be directly compared. Using
startsWith causes invalid elements to be marked as matching.

Fixes: QTBUG-92817
Pick-to: 6.4 6.2 5.15
Change-Id: I439d9325b58fd0aa57fb4ead8db48edb4188ebee
Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io>
This commit is contained in:
Maurice Kalinowski 2022-09-27 20:39:49 +02:00
parent 035c5341e2
commit 56439080fa
2 changed files with 19 additions and 1 deletions

View File

@ -209,9 +209,24 @@ bool QMqttTopicFilter::match(const QMqttTopicName &name, MatchOptions matchOptio
if (d->filter.endsWith(QLatin1Char('#'))) { if (d->filter.endsWith(QLatin1Char('#'))) {
QStringView root = QStringView{d->filter}.left(d->filter.size() - 1); QStringView root = QStringView{d->filter}.left(d->filter.size() - 1);
if (root.isEmpty()) // Filter: #
return true;
if (root.endsWith(QLatin1Char('/'))) // '#' also represents the parent level! if (root.endsWith(QLatin1Char('/'))) // '#' also represents the parent level!
root = root.left(root.size() - 1); root = root.left(root.size() - 1);
return topic.startsWith(root);
const auto filterLevels = root.split(QLatin1Char('/'));
const auto topicLevels = QStringView{topic}.split(QLatin1Char('/'));
if (topicLevels.size() < filterLevels.size())
return false;
for (int i = 0; i < filterLevels.size(); ++i) {
if (filterLevels.at(i) != topicLevels.at(i))
return false;
}
return true;
} }
if (d->filter.contains(QLatin1Char('+'))) { if (d->filter.contains(QLatin1Char('+'))) {

View File

@ -95,6 +95,9 @@ void Tst_QMqttTopicFilter::matches()
QVERIFY(QMqttTopicFilter("$SYS/monitor/+").match(QMqttTopicName("$SYS/monitor/Clients"))); QVERIFY(QMqttTopicFilter("$SYS/monitor/+").match(QMqttTopicName("$SYS/monitor/Clients")));
QVERIFY(QMqttTopicFilter("$SYS/monitor/+").match(QMqttTopicName("$SYS/monitor/Clients"), QMqttTopicFilter::WildcardsDontMatchDollarTopicMatchOption)); QVERIFY(QMqttTopicFilter("$SYS/monitor/+").match(QMqttTopicName("$SYS/monitor/Clients"), QMqttTopicFilter::WildcardsDontMatchDollarTopicMatchOption));
QVERIFY(!QMqttTopicFilter{QLatin1String("x/#")}.match(QLatin1String("xy/foo"))); // QTBUG-92817
QVERIFY(!QMqttTopicFilter{QLatin1String("x/y/#")}.match(QLatin1String("x")));
} }
void Tst_QMqttTopicFilter::usableWithQList() void Tst_QMqttTopicFilter::usableWithQList()