summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarc Mutz <marc.mutz@kdab.com>2017-02-05 14:55:01 +0100
committerMarc Mutz <marc.mutz@kdab.com>2017-02-08 12:34:47 +0000
commit3e43ddd926fd1d96a5d03b272119e02aef54aee9 (patch)
tree6218add75157bfbb0fee0cee7e1d52a937fcf64a
parent06e1f124375569454d70675938f232f6bee396ac (diff)
QStringMatcher: fix setCaseSensitivity() on a non-QString-backed matcher
When a non-QString-backed mode (via the (QChar*, int) ctor) was added for Qt 4.5, the author forgot to adjust the setCaseSensitivity() function. It still uses q_pattern instead of (p.uc, p.len) as the pattern for which to create the skip-table. Since there is no setPattern() overload for this mode, the correctness of the matcher is not harmed by this, but its performance degrades to that of a linear scan: the skip-table, being filled from an empty pattern, will be all-zeros, sending bm_find() into the 'possible match' case at every character. Since matching is still correct, but slow, it's not possible to write a test for this. I did, however, leave my attempts in the auto-test, for when we add QStringView overloads of setPattern() which will then be able to expose the bug. Change-Id: I7b803e8624b0352a0a974900affbbfc0c260d93b Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> (cherry picked from commit 9e5e30fa130e43524d9ff26493023ac966a878cc)
-rw-r--r--src/corelib/tools/qstringmatcher.cpp2
-rw-r--r--tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp13
2 files changed, 12 insertions, 3 deletions
diff --git a/src/corelib/tools/qstringmatcher.cpp b/src/corelib/tools/qstringmatcher.cpp
index 699a94a0a8..099ca19782 100644
--- a/src/corelib/tools/qstringmatcher.cpp
+++ b/src/corelib/tools/qstringmatcher.cpp
@@ -246,7 +246,7 @@ void QStringMatcher::setCaseSensitivity(Qt::CaseSensitivity cs)
{
if (cs == q_cs)
return;
- bm_init_skiptable((const ushort *)q_pattern.unicode(), q_pattern.size(), p.q_skiptable, cs);
+ bm_init_skiptable((const ushort *)p.uc, p.len, p.q_skiptable, cs);
q_cs = cs;
}
diff --git a/tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp b/tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp
index a21e15aac4..c2e42edad3 100644
--- a/tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp
+++ b/tests/auto/corelib/tools/qstringmatcher/tst_qstringmatcher.cpp
@@ -59,12 +59,21 @@ void tst_QStringMatcher::qstringmatcher()
// public Qt::CaseSensitivity caseSensitivity() const
void tst_QStringMatcher::caseSensitivity()
{
- QStringMatcher matcher;
+ const QString haystack = QStringLiteral("foobarFoo");
+ const QStringRef needle = haystack.rightRef(3); // "Foo"
+ QStringMatcher matcher(needle.data(), needle.size());
- matcher.setCaseSensitivity(Qt::CaseSensitive);
QCOMPARE(matcher.caseSensitivity(), Qt::CaseSensitive);
+ QCOMPARE(matcher.indexIn(haystack), 6);
+
matcher.setCaseSensitivity(Qt::CaseInsensitive);
+
QCOMPARE(matcher.caseSensitivity(), Qt::CaseInsensitive);
+ QCOMPARE(matcher.indexIn(haystack), 0);
+
+ matcher.setCaseSensitivity(Qt::CaseSensitive);
+ QCOMPARE(matcher.caseSensitivity(), Qt::CaseSensitive);
+ QCOMPARE(matcher.indexIn(haystack), 6);
}
void tst_QStringMatcher::indexIn_data()