diff options
author | Olivier Goffart <olivier.goffart@nokia.com> | 2010-06-03 11:03:14 +0200 |
---|---|---|
committer | Samuli Piippo <samuli.piippo@digia.com> | 2011-06-09 13:06:06 +0300 |
commit | b31ca7e1384972ebb46e547aa26b8df5ce60cd6e (patch) | |
tree | 57ef0922bd97b8e53f0d9c0330e901ca75d505a0 | |
parent | 0e9b8257e542bb3b6958e90917bad0d1691598e2 (diff) | |
download | qt4-tools-b31ca7e1384972ebb46e547aa26b8df5ce60cd6e.tar.gz |
QString: Fix severals bugs when comparing with QStringRef
the internal ucstricmp and ucstrcmp contains different bugs if the
strings are not 0-terminated, as it is with QStringRef.
- in ucstricmp, even if the pointer are the same, the lenght could
be different
- we used to deference the 'end' pointer, that would be 0 if the
string ends with 0, but we cannot do that in the general case
Task-number: QTBUG-10404
Reviewed-by: Denis
(cherry picked from commit cd003bfcf9a05967893099e8948ba3d8f281aa7d)
-rw-r--r-- | src/corelib/tools/qstring.cpp | 11 | ||||
-rw-r--r-- | tests/auto/qstring/tst_qstring.cpp | 33 |
2 files changed, 40 insertions, 4 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 01d3825529..3f472d33b6 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -111,7 +111,7 @@ int qFindStringBoyerMoore(const QChar *haystack, int haystackLen, int from, static int ucstricmp(const ushort *a, const ushort *ae, const ushort *b, const ushort *be) { if (a == b) - return 0; + return (ae - be); if (a == 0) return 1; if (b == 0) @@ -123,7 +123,7 @@ static int ucstricmp(const ushort *a, const ushort *ae, const ushort *b, const u uint alast = 0; uint blast = 0; - while (a != e) { + while (a < e) { // qDebug() << hex << alast << blast; // qDebug() << hex << "*a=" << *a << "alast=" << alast << "folded=" << foldCase (*a, alast); // qDebug() << hex << "*b=" << *b << "blast=" << blast << "folded=" << foldCase (*b, blast); @@ -152,7 +152,7 @@ static int ucstricmp(const ushort *a, const ushort *ae, const uchar *b) if (b == 0) return -1; - while (a != ae && *b) { + while (a < ae && *b) { int diff = foldCase(*a) - foldCase(*b); if ((diff)) return diff; @@ -4532,9 +4532,12 @@ int QString::compare_helper(const QChar *data1, int length1, QLatin1String s2, return length1; if (cs == Qt::CaseSensitive) { - while (uc != e && *c && *uc == *c) + while (uc < e && *c && *uc == *c) uc++, c++; + if (uc == e) + return -*c; + return *uc - *c; } else { return ucstricmp(uc, e, c); diff --git a/tests/auto/qstring/tst_qstring.cpp b/tests/auto/qstring/tst_qstring.cpp index 26de04e183..5a153dede9 100644 --- a/tests/auto/qstring/tst_qstring.cpp +++ b/tests/auto/qstring/tst_qstring.cpp @@ -202,6 +202,7 @@ private slots: void repeated() const; void repeated_data() const; void task262677remove(); + void QTBUG10404_compareRef(); }; typedef QList<int> IntList; @@ -4680,6 +4681,38 @@ void tst_QString::task262677remove() QVERIFY(driveName == QLatin1String("V:")); } +void tst_QString::QTBUG10404_compareRef() +{ + QString a = "ABCDEFGH"; + + QCOMPARE(QStringRef(&a, 1, 2).compare(QLatin1String("BC")), 0); + QVERIFY(QStringRef(&a, 1, 2).compare(QLatin1String("BCD")) < 0); + QCOMPARE(QStringRef(&a, 1, 2).compare(QLatin1String("Bc"), Qt::CaseInsensitive), 0); + QVERIFY(QStringRef(&a, 1, 2).compare(QLatin1String("bCD"), Qt::CaseInsensitive) < 0); + + QCOMPARE(QStringRef(&a, 1, 2).compare(QString::fromLatin1("BC")), 0); + QVERIFY(QStringRef(&a, 1, 2).compare(QString::fromLatin1("BCD")) < 0); + QCOMPARE(QStringRef(&a, 1, 2).compare(QString::fromLatin1("Bc"), Qt::CaseInsensitive), 0); + QVERIFY(QStringRef(&a, 1, 2).compare(QString::fromLatin1("bCD"), Qt::CaseInsensitive) < 0); + + QCOMPARE(QString::fromLatin1("BC").compare(QStringRef(&a, 1, 2)), 0); + QVERIFY(QString::fromLatin1("BCD").compare(QStringRef(&a, 1, 2)) > 0); + QCOMPARE(QString::fromLatin1("Bc").compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive), 0); + QVERIFY(QString::fromLatin1("bCD").compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive) > 0); + + QCOMPARE(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 2)), 0); + QVERIFY(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 3)) < 0); + QCOMPARE(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive), 0); + QVERIFY(QStringRef(&a, 1, 2).compare(QStringRef(&a, 1, 3), Qt::CaseInsensitive) < 0); + + QString a2 = "ABCDEFGh"; + QCOMPARE(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 2)), 0); + QVERIFY(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 3)) < 0); + QCOMPARE(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 2), Qt::CaseInsensitive), 0); + QVERIFY(QStringRef(&a2, 1, 2).compare(QStringRef(&a, 1, 3), Qt::CaseInsensitive) < 0); +} + + QTEST_APPLESS_MAIN(tst_QString) |