From 6c5eaed92ca838e68745c71ee27adb754a496b8e Mon Sep 17 00:00:00 2001 From: Christian Stenger Date: Fri, 16 Oct 2020 13:38:57 +0200 Subject: Utils: Fix matching wildcards to full paths Fixes: QTCREATORBUG-24792 Change-Id: I82b4edea6260b07e1bdff065b157a4cd044ec629 Reviewed-by: Eike Ziller --- src/libs/utils/filesearch.cpp | 3 +- src/libs/utils/stringutils.cpp | 64 +++++++++++++++++++++++++++++++++++ src/libs/utils/stringutils.h | 7 ++++ src/plugins/cppcheck/cppchecktool.cpp | 3 +- 4 files changed, 75 insertions(+), 2 deletions(-) diff --git a/src/libs/utils/filesearch.cpp b/src/libs/utils/filesearch.cpp index 5601b763a3..bb096e59bf 100644 --- a/src/libs/utils/filesearch.cpp +++ b/src/libs/utils/filesearch.cpp @@ -29,6 +29,7 @@ #include "fileutils.h" #include "mapreduce.h" #include "qtcassert.h" +#include "stringutils.h" #include #include @@ -474,7 +475,7 @@ QString matchCaseReplacement(const QString &originalText, const QString &replace static QList filtersToRegExps(const QStringList &filters) { return Utils::transform(filters, [](const QString &filter) { - return QRegularExpression(QRegularExpression::wildcardToRegularExpression(filter), + return QRegularExpression(Utils::wildcardToRegularExpression(filter), QRegularExpression::CaseInsensitiveOption); }); } diff --git a/src/libs/utils/stringutils.cpp b/src/libs/utils/stringutils.cpp index 888428790b..d8483df552 100644 --- a/src/libs/utils/stringutils.cpp +++ b/src/libs/utils/stringutils.cpp @@ -393,4 +393,68 @@ QString formatElapsedTime(qint64 elapsed) return QCoreApplication::translate("StringUtils", "Elapsed time: %1.").arg(time); } +/* + * Basically QRegularExpression::wildcardToRegularExpression(), but let wildcards match + * path separators as well + */ +QString wildcardToRegularExpression(const QString &original) +{ + const qsizetype wclen = original.size(); + QString rx; + rx.reserve(wclen + wclen / 16); + qsizetype i = 0; + const QChar *wc = original.data(); + + const QLatin1String starEscape(".*"); + const QLatin1String questionMarkEscape("."); + + while (i < wclen) { + const QChar c = wc[i++]; + switch (c.unicode()) { + case '*': + rx += starEscape; + break; + case '?': + rx += questionMarkEscape; + break; + case '\\': + case '$': + case '(': + case ')': + case '+': + case '.': + case '^': + case '{': + case '|': + case '}': + rx += QLatin1Char('\\'); + rx += c; + break; + case '[': + rx += c; + // Support for the [!abc] or [!a-c] syntax + if (i < wclen) { + if (wc[i] == QLatin1Char('!')) { + rx += QLatin1Char('^'); + ++i; + } + + if (i < wclen && wc[i] == QLatin1Char(']')) + rx += wc[i++]; + + while (i < wclen && wc[i] != QLatin1Char(']')) { + if (wc[i] == QLatin1Char('\\')) + rx += QLatin1Char('\\'); + rx += wc[i++]; + } + } + break; + default: + rx += c; + break; + } + } + + return QRegularExpression::anchoredPattern(rx); +} } // namespace Utils diff --git a/src/libs/utils/stringutils.h b/src/libs/utils/stringutils.h index 21a01de359..fbafa7708c 100644 --- a/src/libs/utils/stringutils.h +++ b/src/libs/utils/stringutils.h @@ -104,4 +104,11 @@ T makeUniquelyNumbered(const T &preferred, const Container &reserved) QTCREATOR_UTILS_EXPORT QString formatElapsedTime(qint64 elapsed); +/* This function is only necessary if you need to match the wildcard expression against a + * string that might contain path separators - otherwise + * QRegularExpression::wildcardToRegularExpression() can be used. + * Working around QRegularExpression::wildcardToRegularExpression() taking native separators + * into account and handling them to disallow matching a wildcard characters. + */ +QTCREATOR_UTILS_EXPORT QString wildcardToRegularExpression(const QString &original); } // namespace Utils diff --git a/src/plugins/cppcheck/cppchecktool.cpp b/src/plugins/cppcheck/cppchecktool.cpp index 2c17247d0a..91660020bb 100644 --- a/src/plugins/cppcheck/cppchecktool.cpp +++ b/src/plugins/cppcheck/cppchecktool.cpp @@ -38,6 +38,7 @@ #include #include #include +#include #include @@ -67,7 +68,7 @@ void CppcheckTool::updateOptions(const CppcheckOptions &options) if (trimmedPattern.isEmpty()) continue; - const QRegularExpression re(QRegularExpression::wildcardToRegularExpression(trimmedPattern)); + const QRegularExpression re(Utils::wildcardToRegularExpression(trimmedPattern)); if (re.isValid()) m_filters.push_back(re); } -- cgit v1.2.3