Details
-
Bug
-
Resolution: Done
-
Not Evaluated
-
4.4.3
-
None
-
e7c36fc2e420f1cee4370020b9f50bb5a6dfe92a
Description
In the QRegExp::WildCard mode, it is not possible to escape the metacharacters. For example, "
[.cpp" will not match "[.cpp".
Here is a test case for this problem:
#include <QtTest/QtTest>
class Test : public QObject{
Q_OBJECT
private slots:
void testEscapingWildcard_data()
void testEscapingWildcard()
{ QFETCH(QString, pattern); QRegExp re(pattern); re.setPatternSyntax(QRegExp::Wildcard); QFETCH(QString, teststring); QFETCH(bool, isMatching); QCOMPARE(re.exactMatch(teststring), isMatching); }void testInvalidWildcard_data()
{ QTest::addColumn<QString>("pattern"); QTest::addColumn<bool>("isValid"); QTest::newRow("valid []") << "[abc]" << true; QTest::newRow("invalid [") << "[abc" << false; QTest::newRow("ending [") << "abc[" << false; QTest::newRow("ending ]") << "abc]" << false; QTest::newRow("ending [^") << "abc[^" << false; QTest::newRow("ending [\\") << "abc[\\" << false; QTest::newRow("ending []") << "abc[]" << false; QTest::newRow("ending [[") << "abc[[" << false; }void testInvalidWildcard()
{ QFETCH(QString, pattern); QRegExp re(pattern); re.setPatternSyntax(QRegExp::Wildcard); QFETCH(bool, isValid); QCOMPARE(re.isValid(), isValid); }};
QTEST_MAIN(Test)
#include "test.moc"
And here is a patch to solve the issue:
diff --git a/src/corelib/tools/qregexp.cpp b/src/corelib/tools/qregexp.cpp
index e93b003..61ee2e9 100644
— a/src/corelib/tools/qregexp.cpp
+++ b/src/corelib/tools/qregexp.cpp
@@ -718,47 +718,98 @@ static void mergeInto(QVector<int> *a, const QVector<int> &b)
*/
static QString wc2rx(const QString &wc_str)
{
- int wclen = wc_str.length();
+ const uint wclen = wc_str.length();
QString rx; - int i = 0;
+ uint i = 0;
+ bool isEscaping = false; // the previous character is '\'
const QChar *wc = wc_str.unicode();
+
while (i < wclen) { - QChar c = wc[i++];
+ const QChar c = wc[i++];
switch (c.unicode()) {
case '*': - rx += QLatin1String(".*");
+ if(isEscaping) { + rx += QLatin1String("\\*"); + isEscaping = false; + }else
{ + rx += QLatin1String(".*"); + }break;
+
case '?': - rx += QLatin1Char('.');
+ if(isEscaping) { + rx += QLatin1String("\\?"); + isEscaping = false; + }else
{ + rx += QLatin1Char('.'); + }+
{ + rx += QLatin1String("\\\\"); + }
+ break;
+
+ case '
':
+ if(isEscaping)+ if (i+1 == wclen)
{ // the end + rx += QLatin1String("\\\\"); + }+ // we insert the
later if necessary
+ isEscaping = true;
+
break;
+
case '$':
case '(':
case ')':
case '+':
case '.': - case '
':
case '^':
case ' {': case '|': case '}':
{ + isEscaping = false; + rx += QLatin1Char('\\'); + }
+ if(isEscaping)rx += QLatin1Char('
');
rx += c;
break;
+
case '[': - rx += c;
- if (wc[i] == QLatin1Char('^'))
- rx += wc[i++];
- if (i < wclen) {
- if (rx[i] == QLatin1Char(']'))
+ if(isEscaping) { + isEscaping = false; + rx += QLatin1String("\\["); + }else{
+ rx += c;
+ // first ] is not a closing ]
+ if (i < wclen && wc[i] == QLatin1Char('^'))
rx += wc[i++]; - while (i < wclen && wc[i] != QLatin1Char(']'))
{
- if (wc[i] == QLatin1Char('\\'))
- rx += QLatin1Char('\\');
+ if (i < wclen && rx[i] == QLatin1Char(']'))
rx += wc[i++];
- }
+
{ + if (wc[i] == escapeChar && (i+1 < wclen)) + rx += wc[i++]; + rx += wc[i++]; + }
+ const QLatin1Char escapeChar('
');
+ while (i < wclen && wc[i] != QLatin1Char(']'))+ if(i < wclen)
{ + isEscaping = false; + rx += QLatin1String("\\"); }
+ rx += wc[i++];
+ }
+ break;
+ case ']':
+ if(isEscaping)+ rx += c;
{ + isEscaping = false; + rx += QLatin1String("\\\\"); + }
break;
+
default:
+ if(isEscaping)rx += c;
}
}