Fix crash on reallocateAndGrow

After 6be398 few tests fail/crash with qtcharts.
Fix issue on reallocateAndGraw and avoid accessing
flags on invalid header.

Data::allocate can return invalid header and dataptr,
which takes place if capacity is 0. In code before 6be398
clone method checks if header is not null before resetting
flags. However after b76fbb4 resetting flags is no longer
needed since it is done in allocateGrow.

Task-number: QTBUG-89092
Change-Id: I2fde781dad7a0694a5f17ab716f647c2e35f4ff0
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
(cherry picked from commit b770b7517d30dd17d1096a0bb434677a2b3ff630)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Michal Klocek 2020-12-08 11:04:23 +01:00 committed by Qt Cherry-pick Bot
parent e49e2a4a15
commit 113cd9019d
2 changed files with 58 additions and 1 deletions

View File

@ -189,6 +189,7 @@ public:
QArrayDataPointer dp(allocateGrow(*this, n, where));
if (where == QArrayData::GrowsAtBeginning) {
Q_ASSERT(dp.ptr);
dp.ptr += n;
Q_ASSERT(dp.freeSpaceAtBegin() >= n);
} else {
@ -202,7 +203,6 @@ public:
dp->copyAppend(begin(), begin() + toCopy);
else
dp->moveAppend(begin(), begin() + toCopy);
dp.d->flags = flags();
Q_ASSERT(dp.size == toCopy);
}

View File

@ -264,6 +264,8 @@ private slots:
void insertInt() const;
void insertMovable() const;
void insertCustom() const;
void insertZeroCount_data();
void insertZeroCount() const;
void isEmpty() const;
void last() const;
void lastIndexOf() const;
@ -290,6 +292,9 @@ private slots:
void resizeComplex_data() const;
void resizeComplex() const;
void resizeCtorAndDtor() const;
void resizeToZero() const;
void resizeToTheSameSize_data();
void resizeToTheSameSize() const;
void reverseIterators() const;
void sizeInt() const;
void sizeMovable() const;
@ -1716,6 +1721,26 @@ void tst_QList::insertCustom() const
insert<Custom>();
}
void tst_QList::insertZeroCount_data()
{
QTest::addColumn<int>("pos");
QTest::newRow("0") << 0;
QTest::newRow("1") << 1;
}
void tst_QList::insertZeroCount() const
{
QFETCH(int, pos);
QList<int> x;
x << 0 << 0;
x.insert(pos, 0, 1);
QCOMPARE(x[pos], 0);
QList<int> y;
y = x;
y.insert(pos, 0, 2);
QCOMPARE(y[pos], 0);
}
void tst_QList::isEmpty() const
{
QList<QString> myvec;
@ -2318,6 +2343,38 @@ void tst_QList::resizeCtorAndDtor() const
QCOMPARE(Custom::counter.loadAcquire(), items);
}
void tst_QList::resizeToZero() const
{
QList<int> x;
QList<int> y;
x << 1 << 2;
y = x;
y.resize(0);
QCOMPARE(y.size(), 0);
// grow back
y.resize(x.size());
QCOMPARE(y.size(), x.size());
// default initialized
QCOMPARE(y[0], 0);
QCOMPARE(y[1], 0);
}
void tst_QList::resizeToTheSameSize_data()
{
QTest::addColumn<QList<int>>("x");
QTest::newRow("size 2") << QList({ 1, 2 });
QTest::newRow("size 0") << QList<int>();
}
void tst_QList::resizeToTheSameSize() const
{
QFETCH(QList<int>, x);
QList<int> y;
y = x;
y.resize(x.size());
QCOMPARE(y.size(), x.size());
}
void tst_QList::reverseIterators() const
{
QList<int> v;