From 61d2ff359bb07d45aa5c5f9e55b881e5ba23a623 Mon Sep 17 00:00:00 2001 From: "Vladimir Golovnev (Glassez)" Date: Sun, 14 Mar 2021 18:11:23 +0300 Subject: [PATCH] Use QRegularExpression instead of deprecated QRegExp Now it follows closely the definition of wildcard for glob patterns. The backslash (\) character is not an escape char in this context. In order to match one of the special characters, place it in square brackets (for example, [?]). --- src/app/qtlocalpeer/qtlocalpeer.cpp | 3 ++- src/base/rss/rss_autodownloadrule.cpp | 6 ++---- src/base/rss/rss_parser.cpp | 22 ++++++++++++---------- src/base/utils/string.cpp | 16 ++++++++++++++-- src/base/utils/string.h | 2 +- src/gui/properties/propertieswidget.cpp | 3 ++- src/gui/rss/automatedrssdownloader.cpp | 12 ++++++++++-- src/gui/search/searchjobwidget.cpp | 6 +++--- src/gui/torrentcontentfiltermodel.cpp | 4 ++-- src/gui/transferlistwidget.cpp | 7 +++---- src/webui/webapplication.cpp | 4 ++-- 11 files changed, 53 insertions(+), 32 deletions(-) diff --git a/src/app/qtlocalpeer/qtlocalpeer.cpp b/src/app/qtlocalpeer/qtlocalpeer.cpp index e8345bcd7..5a83963cb 100644 --- a/src/app/qtlocalpeer/qtlocalpeer.cpp +++ b/src/app/qtlocalpeer/qtlocalpeer.cpp @@ -79,6 +79,7 @@ #include #include #include +#include #include "base/utils/misc.h" @@ -108,7 +109,7 @@ QtLocalPeer::QtLocalPeer(QObject* parent, const QString &appId) #endif prefix = id.section(QLatin1Char('/'), -1); } - prefix.remove(QRegExp("[^a-zA-Z]")); + prefix.remove(QRegularExpression("[^a-zA-Z]")); prefix.truncate(6); QByteArray idc = id.toUtf8(); diff --git a/src/base/rss/rss_autodownloadrule.cpp b/src/base/rss/rss_autodownloadrule.cpp index ac47fbb53..32f79937e 100644 --- a/src/base/rss/rss_autodownloadrule.cpp +++ b/src/base/rss/rss_autodownloadrule.cpp @@ -213,10 +213,8 @@ QRegularExpression AutoDownloadRule::cachedRegex(const QString &expression, cons QRegularExpression ®ex = m_dataPtr->cachedRegexes[expression]; if (regex.pattern().isEmpty()) { - regex = QRegularExpression - { - (isRegex ? expression : Utils::String::wildcardToRegex(expression)) - , QRegularExpression::CaseInsensitiveOption}; + const QString pattern = (isRegex ? expression : Utils::String::wildcardToRegexPattern(expression)); + regex = QRegularExpression {pattern, QRegularExpression::CaseInsensitiveOption}; } return regex; diff --git a/src/base/rss/rss_parser.cpp b/src/base/rss/rss_parser.cpp index 66dc5376d..4948518e7 100644 --- a/src/base/rss/rss_parser.cpp +++ b/src/base/rss/rss_parser.cpp @@ -34,7 +34,7 @@ #include #include #include -#include +#include #include #include #include @@ -391,12 +391,13 @@ namespace int nmin = 8; int nsec = 9; // Also accept obsolete form "Weekday, DD-Mon-YY HH:MM:SS ±hhmm" - QRegExp rx("^(?:([A-Z][a-z]+),\\s*)?(\\d{1,2})(\\s+|-)([^-\\s]+)(\\s+|-)(\\d{2,4})\\s+(\\d\\d):(\\d\\d)(?::(\\d\\d))?\\s+(\\S+)$"); + QRegularExpression rx {"^(?:([A-Z][a-z]+),\\s*)?(\\d{1,2})(\\s+|-)([^-\\s]+)(\\s+|-)(\\d{2,4})\\s+(\\d\\d):(\\d\\d)(?::(\\d\\d))?\\s+(\\S+)$"}; + QRegularExpressionMatch rxMatch; QStringList parts; - if (!str.indexOf(rx)) + if (str.indexOf(rx, 0, &rxMatch) == 0) { // Check that if date has '-' separators, both separators are '-'. - parts = rx.capturedTexts(); + parts = rxMatch.capturedTexts(); const bool h1 = (parts[3] == QLatin1String("-")); const bool h2 = (parts[5] == QLatin1String("-")); if (h1 != h2) @@ -405,9 +406,10 @@ namespace else { // Check for the obsolete form "Wdy Mon DD HH:MM:SS YYYY" - rx = QRegExp("^([A-Z][a-z]+)\\s+(\\S+)\\s+(\\d\\d)\\s+(\\d\\d):(\\d\\d):(\\d\\d)\\s+(\\d\\d\\d\\d)$"); - if (str.indexOf(rx)) + rx = QRegularExpression {"^([A-Z][a-z]+)\\s+(\\S+)\\s+(\\d\\d)\\s+(\\d\\d):(\\d\\d):(\\d\\d)\\s+(\\d\\d\\d\\d)$"}; + if (str.indexOf(rx, 0, &rxMatch) != 0) return QDateTime::currentDateTime(); + nyear = 7; nmonth = 2; nday = 3; @@ -415,7 +417,7 @@ namespace nhour = 4; nmin = 5; nsec = 6; - parts = rx.capturedTexts(); + parts = rxMatch.capturedTexts(); } bool ok[4]; @@ -463,11 +465,11 @@ namespace bool negOffset = false; if (parts.count() > 10) { - rx = QRegExp("^([+-])(\\d\\d)(\\d\\d)$"); - if (!parts[10].indexOf(rx)) + rx = QRegularExpression {"^([+-])(\\d\\d)(\\d\\d)$"}; + if (parts[10].indexOf(rx, 0, &rxMatch) == 0) { // It's a UTC offset ±hhmm - parts = rx.capturedTexts(); + parts = rxMatch.capturedTexts(); offset = parts[2].toInt(&ok[0]) * 3600; const int offsetMin = parts[3].toInt(&ok[1]); if (!ok[0] || !ok[1] || offsetMin > 59) diff --git a/src/base/utils/string.cpp b/src/base/utils/string.cpp index 8f5d0c263..7256352c4 100644 --- a/src/base/utils/string.cpp +++ b/src/base/utils/string.cpp @@ -33,10 +33,15 @@ #include #include -#include #include #include +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +#include +#else +#include +#endif + #if defined(Q_OS_MACOS) || defined(__MINGW32__) #define QBT_USES_QTHREADSTORAGE #include @@ -181,14 +186,21 @@ QString Utils::String::fromDouble(const double n, const int precision) return QLocale::system().toString(std::floor(n * prec) / prec, 'f', precision); } +#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)) +QString Utils::String::wildcardToRegexPattern(const QString &pattern) +{ + return QRegularExpression::wildcardToRegularExpression(pattern, QRegularExpression::UnanchoredWildcardConversion); +} +#else // This is marked as internal in QRegExp.cpp, but is exported. The alternative would be to // copy the code from QRegExp::wc2rx(). QString qt_regexp_toCanonical(const QString &pattern, QRegExp::PatternSyntax patternSyntax); -QString Utils::String::wildcardToRegex(const QString &pattern) +QString Utils::String::wildcardToRegexPattern(const QString &pattern) { return qt_regexp_toCanonical(pattern, QRegExp::Wildcard); } +#endif std::optional Utils::String::parseBool(const QString &string) { diff --git a/src/base/utils/string.h b/src/base/utils/string.h index 30bf38a8e..7531a312b 100644 --- a/src/base/utils/string.h +++ b/src/base/utils/string.h @@ -50,7 +50,7 @@ namespace Utils::String return (naturalCompare(left, right, caseSensitivity) < 0); } - QString wildcardToRegex(const QString &pattern); + QString wildcardToRegexPattern(const QString &pattern); template T unquote(const T &str, const QString "es = QChar('"')) diff --git a/src/gui/properties/propertieswidget.cpp b/src/gui/properties/propertieswidget.cpp index 48d901f84..b05a592e8 100644 --- a/src/gui/properties/propertieswidget.cpp +++ b/src/gui/properties/propertieswidget.cpp @@ -825,7 +825,8 @@ void PropertiesWidget::filteredFilesChanged() void PropertiesWidget::filterText(const QString &filter) { - m_propListModel->setFilterRegExp(QRegExp(filter, Qt::CaseInsensitive, QRegExp::WildcardUnix)); + const QString pattern = Utils::String::wildcardToRegexPattern(filter); + m_propListModel->setFilterRegularExpression(QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption)); if (filter.isEmpty()) { m_ui->filesList->collapseAll(); diff --git a/src/gui/rss/automatedrssdownloader.cpp b/src/gui/rss/automatedrssdownloader.cpp index 4cf58947a..fb0313799 100644 --- a/src/gui/rss/automatedrssdownloader.cpp +++ b/src/gui/rss/automatedrssdownloader.cpp @@ -719,10 +719,14 @@ void AutomatedRssDownloader::updateMustLineValidity() { QStringList tokens; if (isRegex) + { tokens << text; + } else + { for (const QString &token : asConst(text.split('|'))) - tokens << Utils::String::wildcardToRegex(token); + tokens << Utils::String::wildcardToRegexPattern(token); + } for (const QString &token : asConst(tokens)) { @@ -762,10 +766,14 @@ void AutomatedRssDownloader::updateMustNotLineValidity() { QStringList tokens; if (isRegex) + { tokens << text; + } else + { for (const QString &token : asConst(text.split('|'))) - tokens << Utils::String::wildcardToRegex(token); + tokens << Utils::String::wildcardToRegexPattern(token); + } for (const QString &token : asConst(tokens)) { diff --git a/src/gui/search/searchjobwidget.cpp b/src/gui/search/searchjobwidget.cpp index 74fd4702f..54272432a 100644 --- a/src/gui/search/searchjobwidget.cpp +++ b/src/gui/search/searchjobwidget.cpp @@ -365,9 +365,9 @@ void SearchJobWidget::fillFilterComboBoxes() void SearchJobWidget::filterSearchResults(const QString &name) { - const QRegExp::PatternSyntax patternSyntax = Preferences::instance()->getRegexAsFilteringPatternForSearchJob() - ? QRegExp::RegExp : QRegExp::WildcardUnix; - m_proxyModel->setFilterRegExp(QRegExp(name, Qt::CaseInsensitive, patternSyntax)); + const QString pattern = (Preferences::instance()->getRegexAsFilteringPatternForSearchJob() + ? name : Utils::String::wildcardToRegexPattern(name)); + m_proxyModel->setFilterRegularExpression(QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption)); updateResultsCount(); } diff --git a/src/gui/torrentcontentfiltermodel.cpp b/src/gui/torrentcontentfiltermodel.cpp index 9659129ca..465a21164 100644 --- a/src/gui/torrentcontentfiltermodel.cpp +++ b/src/gui/torrentcontentfiltermodel.cpp @@ -129,7 +129,7 @@ bool TorrentContentFilterModel::hasFiltered(const QModelIndex &folder) const // this should be called only with folders // check if the folder name itself matches the filter string QString name = folder.data().toString(); - if (name.contains(filterRegExp())) + if (name.contains(filterRegularExpression())) return true; for (int child = 0; child < m_model->rowCount(folder); ++child) { @@ -141,7 +141,7 @@ bool TorrentContentFilterModel::hasFiltered(const QModelIndex &folder) const continue; } name = childIndex.data().toString(); - if (name.contains(filterRegExp())) + if (name.contains(filterRegularExpression())) return true; } diff --git a/src/gui/transferlistwidget.cpp b/src/gui/transferlistwidget.cpp index ca1abb8f6..17d3719b1 100644 --- a/src/gui/transferlistwidget.cpp +++ b/src/gui/transferlistwidget.cpp @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include @@ -1131,9 +1130,9 @@ void TransferListWidget::applyTrackerFilter(const QSet &t void TransferListWidget::applyNameFilter(const QString &name) { - const QRegExp::PatternSyntax patternSyntax = Preferences::instance()->getRegexAsFilteringPatternForTransferList() - ? QRegExp::RegExp : QRegExp::WildcardUnix; - m_sortFilterModel->setFilterRegExp(QRegExp(name, Qt::CaseInsensitive, patternSyntax)); + const QString pattern = (Preferences::instance()->getRegexAsFilteringPatternForTransferList() + ? name : Utils::String::wildcardToRegexPattern(name)); + m_sortFilterModel->setFilterRegularExpression(QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption)); } void TransferListWidget::applyStatusFilter(int f) diff --git a/src/webui/webapplication.cpp b/src/webui/webapplication.cpp index 372229c13..b2e99b21c 100644 --- a/src/webui/webapplication.cpp +++ b/src/webui/webapplication.cpp @@ -38,7 +38,7 @@ #include #include #include -#include +#include #include #include "base/algorithm.h" @@ -693,7 +693,7 @@ bool WebApplication::validateHostHeader(const QStringList &domains) const // try matching host header with domain list for (const auto &domain : domains) { - QRegExp domainRegex(domain, Qt::CaseInsensitive, QRegExp::Wildcard); + const QRegularExpression domainRegex {Utils::String::wildcardToRegexPattern(domain), QRegularExpression::CaseInsensitiveOption}; if (requestHost.contains(domainRegex)) return true; }