Correct regex escape logic
* Fixes #7776 Implement QRegularExpression::escape within Tools::convertToRegex to allow usage on older Qt versions. Also wrap EXACT_MODIFIER patterns in a non-capture group to prevent misinterpreted regex.
This commit is contained in:
committed by
Jonathan White
parent
924eb6dbc4
commit
e16c007d43
@@ -224,7 +224,7 @@ void TestEntrySearcher::testSearchTermParser()
|
||||
QCOMPARE(terms.length(), 2);
|
||||
|
||||
QCOMPARE(terms[0].field, EntrySearcher::Field::Url);
|
||||
QCOMPARE(terms[0].regex.pattern(), QString("^.*\\.google\\.com$"));
|
||||
QCOMPARE(terms[0].regex.pattern(), QString("^(?:.*\\.google\\.com)$"));
|
||||
|
||||
QCOMPARE(terms[1].field, EntrySearcher::Field::Username);
|
||||
QCOMPARE(terms[1].regex.pattern(), QString("\\d+\\w{2}"));
|
||||
@@ -237,7 +237,7 @@ void TestEntrySearcher::testSearchTermParser()
|
||||
|
||||
QCOMPARE(terms[0].field, EntrySearcher::Field::AttributeValue);
|
||||
QCOMPARE(terms[0].word, QString("abc"));
|
||||
QCOMPARE(terms[0].regex.pattern(), QString("^efg$"));
|
||||
QCOMPARE(terms[0].regex.pattern(), QString("^(?:efg)$"));
|
||||
|
||||
QCOMPARE(terms[1].field, EntrySearcher::Field::AttributeValue);
|
||||
QCOMPARE(terms[1].word, QString("def"));
|
||||
|
||||
@@ -82,6 +82,11 @@ void TestFdoSecrets::testSpecialCharsInAttributeValue()
|
||||
QCOMPARE(res.count(), 1);
|
||||
QCOMPARE(res[0]->title(), QStringLiteral("titleB"));
|
||||
}
|
||||
{
|
||||
const auto term = Collection::attributeToTerm("testAttribute", "v|");
|
||||
const auto res = EntrySearcher().search({term}, root.data());
|
||||
QCOMPARE(res.count(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void TestFdoSecrets::testDBusPathParse()
|
||||
|
||||
@@ -165,6 +165,34 @@ void TestTools::testBackupFilePatternSubstitution()
|
||||
QCOMPARE(Tools::substituteBackupFilePath(pattern, dbFilePath), expectedSubstitution);
|
||||
}
|
||||
|
||||
void TestTools::testEscapeRegex_data()
|
||||
{
|
||||
QTest::addColumn<QString>("input");
|
||||
QTest::addColumn<QString>("expected");
|
||||
|
||||
QString all_regular_characters = "0123456789";
|
||||
for (char c = 'a'; c != 'z'; ++c) {
|
||||
all_regular_characters += QChar::fromLatin1(c);
|
||||
}
|
||||
for (char c = 'A'; c != 'Z'; ++c) {
|
||||
all_regular_characters += QChar::fromLatin1(c);
|
||||
}
|
||||
|
||||
QTest::newRow("Regular characters should not be escaped") << all_regular_characters << all_regular_characters;
|
||||
QTest::newRow("Special characters should be escaped") << R"(.^$*+-?()[]{}|\)"
|
||||
<< R"(\.\^\$\*\+\-\?\(\)\[\]\{\}\|\\)";
|
||||
QTest::newRow("Null character") << QString::fromLatin1("ab\0c", 4) << "ab\\0c";
|
||||
}
|
||||
|
||||
void TestTools::testEscapeRegex()
|
||||
{
|
||||
QFETCH(QString, input);
|
||||
QFETCH(QString, expected);
|
||||
|
||||
auto actual = Tools::escapeRegex(input);
|
||||
QCOMPARE(actual, expected);
|
||||
}
|
||||
|
||||
void TestTools::testConvertToRegex()
|
||||
{
|
||||
QFETCH(QString, input);
|
||||
@@ -185,16 +213,29 @@ void TestTools::testConvertToRegex_data()
|
||||
|
||||
QTest::newRow("No Options") << input << static_cast<int>(Tools::RegexConvertOpts::DEFAULT)
|
||||
<< QString(R"(te|st*t?[5]^(test);',.)");
|
||||
// Escape regex
|
||||
QTest::newRow("Escape Regex") << input << static_cast<int>(Tools::RegexConvertOpts::ESCAPE_REGEX)
|
||||
<< Tools::escapeRegex(input);
|
||||
QTest::newRow("Escape Regex and exact match")
|
||||
<< input << static_cast<int>(Tools::RegexConvertOpts::ESCAPE_REGEX | Tools::RegexConvertOpts::EXACT_MATCH)
|
||||
<< "^(?:" + Tools::escapeRegex(input) + ")$";
|
||||
|
||||
// Exact match does not escape the pattern
|
||||
QTest::newRow("Exact Match") << input << static_cast<int>(Tools::RegexConvertOpts::EXACT_MATCH)
|
||||
<< QString(R"(^te|st*t?[5]^(test);',.$)");
|
||||
<< QString(R"(^(?:te|st*t?[5]^(test);',.)$)");
|
||||
|
||||
// Exact match with improper regex
|
||||
QTest::newRow("Exact Match") << ")av(" << static_cast<int>(Tools::RegexConvertOpts::EXACT_MATCH)
|
||||
<< QString(R"(^(?:)av()$)");
|
||||
|
||||
QTest::newRow("Exact Match & Wildcard")
|
||||
<< input << static_cast<int>(Tools::RegexConvertOpts::EXACT_MATCH | Tools::RegexConvertOpts::WILDCARD_ALL)
|
||||
<< QString(R"(^te|st.*t.\[5\]\^\(test\);'\,\.$)");
|
||||
<< QString(R"(^(?:te|st.*t.\[5\]\^\(test\)\;\'\,\.)$)");
|
||||
QTest::newRow("Wildcard Single Match") << input << static_cast<int>(Tools::RegexConvertOpts::WILDCARD_SINGLE_MATCH)
|
||||
<< QString(R"(te\|st\*t.\[5\]\^\(test\);'\,\.)");
|
||||
<< QString(R"(te\|st\*t.\[5\]\^\(test\)\;\'\,\.)");
|
||||
QTest::newRow("Wildcard OR") << input << static_cast<int>(Tools::RegexConvertOpts::WILDCARD_LOGICAL_OR)
|
||||
<< QString(R"(te|st\*t\?\[5\]\^\(test\);'\,\.)");
|
||||
<< QString(R"(te|st\*t\?\[5\]\^\(test\)\;\'\,\.)");
|
||||
QTest::newRow("Wildcard Unlimited Match")
|
||||
<< input << static_cast<int>(Tools::RegexConvertOpts::WILDCARD_UNLIMITED_MATCH)
|
||||
<< QString(R"(te\|st.*t\?\[5\]\^\(test\);'\,\.)");
|
||||
<< QString(R"(te\|st.*t\?\[5\]\^\(test\)\;\'\,\.)");
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ private slots:
|
||||
void testValidUuid();
|
||||
void testBackupFilePatternSubstitution_data();
|
||||
void testBackupFilePatternSubstitution();
|
||||
void testEscapeRegex();
|
||||
void testEscapeRegex_data();
|
||||
void testConvertToRegex();
|
||||
void testConvertToRegex_data();
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user