Fix QString:mid and midRef, again

In commit 75286739 it was assumed that negative positions shouldn't
influence the size of the returned substring. That however changes
behaviour that was depended on even inside Qt.

With this change, the old behaviour is reestablished.

A negative value of n is still taken to mean "all the way to the end",
regardless of position, and overflows are still avoided.

Change-Id: I7d6ed17cc5e274c7c7ddf0eb0c3238e1159ec4f6
Reviewed-by: Kent Hansen <kent.hansen@nokia.com>
Reviewed-by: Bradley T. Hughes <bradley.hughes@nokia.com>
This commit is contained in:
João Abecasis 2012-03-12 12:58:19 +01:00 committed by Qt by Nokia
parent d5a85940f7
commit e57e2f3e32
2 changed files with 60 additions and 12 deletions

View File

@ -3375,9 +3375,15 @@ QString QString::mid(int position, int n) const
{ {
if (position > d->size) if (position > d->size)
return QString(); return QString();
if (position < 0) if (position < 0) {
if (n < 0 || n + position >= d->size)
return *this;
if (n + position <= 0)
return QString();
n += position;
position = 0; position = 0;
if (n < 0 || n > d->size - position) } else if (n < 0 || n > d->size - position)
n = d->size - position; n = d->size - position;
if (position == 0 && n == d->size) if (position == 0 && n == d->size)
return *this; return *this;
@ -8040,9 +8046,15 @@ QStringRef QString::midRef(int position, int n) const
{ {
if (position > d->size) if (position > d->size)
return QStringRef(); return QStringRef();
if (position < 0) if (position < 0) {
if (n < 0 || n + position >= d->size)
return QStringRef(this, 0, d->size);
if (n + position <= 0)
return QStringRef();
n += position;
position = 0; position = 0;
if (n < 0 || n > d->size - position) } else if (n < 0 || n > d->size - position)
n = d->size - position; n = d->size - position;
return QStringRef(this, position, n); return QStringRef(this, position, n);
} }

View File

@ -1421,8 +1421,14 @@ void tst_QString::mid()
QVERIFY(a.mid(9999).isNull()); QVERIFY(a.mid(9999).isNull());
QVERIFY(a.mid(9999,1).isNull()); QVERIFY(a.mid(9999,1).isNull());
QCOMPARE(a.mid(-1, 6), QString("ABCDEF")); QCOMPARE(a.mid(-1, 6), a.mid(0, 5));
QCOMPARE(a.mid(-100, 6), QString("ABCDEF")); QVERIFY(a.mid(-100, 6).isEmpty());
QVERIFY(a.mid(INT_MIN, 0).isEmpty());
QCOMPARE(a.mid(INT_MIN, -1), a);
QVERIFY(a.mid(INT_MIN, INT_MAX).isNull());
QVERIFY(a.mid(INT_MIN + 1, INT_MAX).isEmpty());
QCOMPARE(a.mid(INT_MIN + 2, INT_MAX), a.left(1));
QCOMPARE(a.mid(INT_MIN + a.size() + 1, INT_MAX), a);
QVERIFY(a.mid(INT_MAX).isNull()); QVERIFY(a.mid(INT_MAX).isNull());
QVERIFY(a.mid(INT_MAX, INT_MAX).isNull()); QVERIFY(a.mid(INT_MAX, INT_MAX).isNull());
QCOMPARE(a.mid(-5, INT_MAX), a); QCOMPARE(a.mid(-5, INT_MAX), a);
@ -1441,6 +1447,12 @@ void tst_QString::mid()
QVERIFY(n.mid(-1, 6).isNull()); QVERIFY(n.mid(-1, 6).isNull());
QVERIFY(n.mid(-100, 6).isNull()); QVERIFY(n.mid(-100, 6).isNull());
QVERIFY(n.mid(INT_MIN, 0).isNull());
QVERIFY(n.mid(INT_MIN, -1).isNull());
QVERIFY(n.mid(INT_MIN, INT_MAX).isNull());
QVERIFY(n.mid(INT_MIN + 1, INT_MAX).isNull());
QVERIFY(n.mid(INT_MIN + 2, INT_MAX).isNull());
QVERIFY(n.mid(INT_MIN + n.size() + 1, INT_MAX).isNull());
QVERIFY(n.mid(INT_MAX).isNull()); QVERIFY(n.mid(INT_MAX).isNull());
QVERIFY(n.mid(INT_MAX, INT_MAX).isNull()); QVERIFY(n.mid(INT_MAX, INT_MAX).isNull());
QVERIFY(n.mid(-5, INT_MAX).isNull()); QVERIFY(n.mid(-5, INT_MAX).isNull());
@ -1455,8 +1467,14 @@ void tst_QString::mid()
QCOMPARE(x.mid(5, 4), QString("pine")); QCOMPARE(x.mid(5, 4), QString("pine"));
QCOMPARE(x.mid(5), QString("pineapples")); QCOMPARE(x.mid(5), QString("pineapples"));
QCOMPARE(x.mid(-1, 6), QString("Nine p")); QCOMPARE(x.mid(-1, 6), x.mid(0, 5));
QCOMPARE(x.mid(-100, 6), QString("Nine p")); QVERIFY(x.mid(-100, 6).isEmpty());
QVERIFY(x.mid(INT_MIN, 0).isEmpty());
QCOMPARE(x.mid(INT_MIN, -1), x);
QVERIFY(x.mid(INT_MIN, INT_MAX).isNull());
QVERIFY(x.mid(INT_MIN + 1, INT_MAX).isEmpty());
QCOMPARE(x.mid(INT_MIN + 2, INT_MAX), x.left(1));
QCOMPARE(x.mid(INT_MIN + x.size() + 1, INT_MAX), x);
QVERIFY(x.mid(INT_MAX).isNull()); QVERIFY(x.mid(INT_MAX).isNull());
QVERIFY(x.mid(INT_MAX, INT_MAX).isNull()); QVERIFY(x.mid(INT_MAX, INT_MAX).isNull());
QCOMPARE(x.mid(-5, INT_MAX), x); QCOMPARE(x.mid(-5, INT_MAX), x);
@ -1482,8 +1500,14 @@ void tst_QString::midRef()
QVERIFY(a.midRef(9999).toString().isEmpty()); QVERIFY(a.midRef(9999).toString().isEmpty());
QVERIFY(a.midRef(9999,1).toString().isEmpty()); QVERIFY(a.midRef(9999,1).toString().isEmpty());
QCOMPARE(a.midRef(-1, 6).toString(), QString("ABCDEF")); QCOMPARE(a.midRef(-1, 6), a.midRef(0, 5));
QCOMPARE(a.midRef(-100, 6).toString(), QString("ABCDEF")); QVERIFY(a.midRef(-100, 6).isEmpty());
QVERIFY(a.midRef(INT_MIN, 0).isEmpty());
QCOMPARE(a.midRef(INT_MIN, -1).toString(), a);
QVERIFY(a.midRef(INT_MIN, INT_MAX).isNull());
QVERIFY(a.midRef(INT_MIN + 1, INT_MAX).isEmpty());
QCOMPARE(a.midRef(INT_MIN + 2, INT_MAX), a.leftRef(1));
QCOMPARE(a.midRef(INT_MIN + a.size() + 1, INT_MAX).toString(), a);
QVERIFY(a.midRef(INT_MAX).isNull()); QVERIFY(a.midRef(INT_MAX).isNull());
QVERIFY(a.midRef(INT_MAX, INT_MAX).isNull()); QVERIFY(a.midRef(INT_MAX, INT_MAX).isNull());
QCOMPARE(a.midRef(-5, INT_MAX).toString(), a); QCOMPARE(a.midRef(-5, INT_MAX).toString(), a);
@ -1502,6 +1526,12 @@ void tst_QString::midRef()
QVERIFY(n.midRef(-1, 6).isNull()); QVERIFY(n.midRef(-1, 6).isNull());
QVERIFY(n.midRef(-100, 6).isNull()); QVERIFY(n.midRef(-100, 6).isNull());
QVERIFY(n.midRef(INT_MIN, 0).isNull());
QVERIFY(n.midRef(INT_MIN, -1).isNull());
QVERIFY(n.midRef(INT_MIN, INT_MAX).isNull());
QVERIFY(n.midRef(INT_MIN + 1, INT_MAX).isNull());
QVERIFY(n.midRef(INT_MIN + 2, INT_MAX).isNull());
QVERIFY(n.midRef(INT_MIN + n.size() + 1, INT_MAX).isNull());
QVERIFY(n.midRef(INT_MAX).isNull()); QVERIFY(n.midRef(INT_MAX).isNull());
QVERIFY(n.midRef(INT_MAX, INT_MAX).isNull()); QVERIFY(n.midRef(INT_MAX, INT_MAX).isNull());
QVERIFY(n.midRef(-5, INT_MAX).isNull()); QVERIFY(n.midRef(-5, INT_MAX).isNull());
@ -1516,8 +1546,14 @@ void tst_QString::midRef()
QCOMPARE(x.midRef(5, 4).toString(), QString("pine")); QCOMPARE(x.midRef(5, 4).toString(), QString("pine"));
QCOMPARE(x.midRef(5).toString(), QString("pineapples")); QCOMPARE(x.midRef(5).toString(), QString("pineapples"));
QCOMPARE(x.midRef(-1, 6).toString(), QString("Nine p")); QCOMPARE(x.midRef(-1, 6), x.midRef(0, 5));
QCOMPARE(x.midRef(-100, 6).toString(), QString("Nine p")); QVERIFY(x.midRef(-100, 6).isEmpty());
QVERIFY(x.midRef(INT_MIN, 0).isEmpty());
QCOMPARE(x.midRef(INT_MIN, -1).toString(), x);
QVERIFY(x.midRef(INT_MIN, INT_MAX).isNull());
QVERIFY(x.midRef(INT_MIN + 1, INT_MAX).isEmpty());
QCOMPARE(x.midRef(INT_MIN + 2, INT_MAX), x.leftRef(1));
QCOMPARE(x.midRef(INT_MIN + x.size() + 1, INT_MAX).toString(), x);
QVERIFY(x.midRef(INT_MAX).isNull()); QVERIFY(x.midRef(INT_MAX).isNull());
QVERIFY(x.midRef(INT_MAX, INT_MAX).isNull()); QVERIFY(x.midRef(INT_MAX, INT_MAX).isNull());
QCOMPARE(x.midRef(-5, INT_MAX).toString(), x); QCOMPARE(x.midRef(-5, INT_MAX).toString(), x);