summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOlivier Goffart <olivier.goffart@nokia.com>2010-06-03 09:03:14 (GMT)
committerOlivier Goffart <olivier.goffart@nokia.com>2010-06-03 09:28:19 (GMT)
commitcd003bfcf9a05967893099e8948ba3d8f281aa7d (patch)
treec9e5afc64bf1d33bbf6121f64c03ba20fc2ecdf8
parent9ecba4c0c963272bbbac627a6742153b5f6f361f (diff)
downloadQt-cd003bfcf9a05967893099e8948ba3d8f281aa7d.zip
Qt-cd003bfcf9a05967893099e8948ba3d8f281aa7d.tar.gz
Qt-cd003bfcf9a05967893099e8948ba3d8f281aa7d.tar.bz2
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
-rw-r--r--src/corelib/tools/qstring.cpp11
-rw-r--r--tests/auto/qstring/tst_qstring.cpp33
2 files changed, 40 insertions, 4 deletions
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 6acbcec..acb0cb4 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -113,7 +113,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)
@@ -125,7 +125,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);
@@ -154,7 +154,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;
@@ -4640,9 +4640,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 1bea4b7..c887936 100644
--- a/tests/auto/qstring/tst_qstring.cpp
+++ b/tests/auto/qstring/tst_qstring.cpp
@@ -207,6 +207,7 @@ private slots:
void repeated() const;
void repeated_data() const;
void task262677remove();
+ void QTBUG10404_compareRef();
};
typedef QList<int> IntList;
@@ -4828,6 +4829,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)