QString/QByteArray: add missing Q_CHECK_PTR

So these two classes throw when trying to allocate silly sizes or in OOM
conditions.

We probably want to move these Q_CHECK_POINTER into QTypedArrayData but
I didn't want to do that in this commit.

Task-number: QTBUG-88256
Task-number: QTBUG-88253
Change-Id: Ifc61bb80b9bf48a386abfffd1648176111770174
Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
(cherry picked from commit aab5c8e5486a6484feddfae0b04fd39fd244d9b9)
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Thiago Macieira 2020-11-16 12:36:12 -08:00
parent 07b6b25c4c
commit f77caf4c60
4 changed files with 20 additions and 0 deletions

View File

@ -1668,6 +1668,7 @@ QByteArray::QByteArray(const char *data, qsizetype size)
d = DataPointer::fromRawData(&_empty, 0);
} else {
d = DataPointer(Data::allocate(size), size);
Q_CHECK_PTR(d.data());
memcpy(d.data(), data, size);
d.data()[size] = '\0';
}
@ -1686,6 +1687,7 @@ QByteArray::QByteArray(qsizetype size, char ch)
d = DataPointer::fromRawData(&_empty, 0);
} else {
d = DataPointer(Data::allocate(size), size);
Q_CHECK_PTR(d.data());
memset(d.data(), ch, size);
d.data()[size] = '\0';
}
@ -1703,6 +1705,7 @@ QByteArray::QByteArray(qsizetype size, Qt::Initialization)
d = DataPointer::fromRawData(&_empty, 0);
} else {
d = DataPointer(Data::allocate(size), size);
Q_CHECK_PTR(d.data());
d.data()[size] = '\0';
}
}
@ -1766,6 +1769,7 @@ void QByteArray::reallocData(qsizetype alloc, QArrayData::AllocationOption optio
if (d->needsDetach() || cannotUseReallocate) {
DataPointer dd(Data::allocate(alloc, option), qMin(alloc, d.size));
Q_CHECK_PTR(dd.data());
if (dd.size > 0)
::memcpy(dd.data(), d.data(), dd.size);
dd.data()[dd.size] = 0;
@ -1782,6 +1786,7 @@ void QByteArray::reallocGrowData(qsizetype n)
if (d->needsDetach()) {
DataPointer dd(DataPointer::allocateGrow(d, n, QArrayData::GrowsAtEnd));
Q_CHECK_PTR(dd.data());
dd->copyAppend(d.data(), d.data() + d.size);
dd.data()[dd.size] = 0;
d = dd;
@ -2000,6 +2005,7 @@ QByteArray &QByteArray::insert(qsizetype i, QByteArrayView data)
DataPointer detached{}; // construction is free
if (d->needsDetach() || i + size - d->size > d.freeSpaceAtEnd()) {
detached = DataPointer::allocateGrow(d, i + size - d->size, Data::GrowsAtEnd);
Q_CHECK_PTR(detached.data());
detached->copyAppend(d.constBegin(), d.constEnd());
d.swap(detached);
}
@ -2081,6 +2087,7 @@ QByteArray &QByteArray::insert(qsizetype i, qsizetype count, char ch)
// handle this specially, as QArrayDataOps::insert() doesn't handle out of bounds positions
if (d->needsDetach() || i + count - d->size > d.freeSpaceAtEnd()) {
DataPointer detached(DataPointer::allocateGrow(d, i + count - d->size, Data::GrowsAtEnd));
Q_CHECK_PTR(detached.data());
detached->copyAppend(d.constBegin(), d.constEnd());
d.swap(detached);
}

View File

@ -2261,6 +2261,7 @@ QString::QString(const QChar *unicode, qsizetype size)
d = DataPointer::fromRawData(&_empty, 0);
} else {
d = DataPointer(Data::allocate(size), size);
Q_CHECK_PTR(d.data());
memcpy(d.data(), unicode, size * sizeof(QChar));
d.data()[size] = '\0';
}
@ -2279,6 +2280,7 @@ QString::QString(qsizetype size, QChar ch)
d = DataPointer::fromRawData(&_empty, 0);
} else {
d = DataPointer(Data::allocate(size), size);
Q_CHECK_PTR(d.data());
d.data()[size] = '\0';
char16_t *i = d.data() + size;
char16_t *b = d.data();
@ -2300,6 +2302,7 @@ QString::QString(qsizetype size, Qt::Initialization)
d = DataPointer::fromRawData(&_empty, 0);
} else {
d = DataPointer(Data::allocate(size), size);
Q_CHECK_PTR(d.data());
d.data()[size] = '\0';
}
}
@ -2317,6 +2320,7 @@ QString::QString(qsizetype size, Qt::Initialization)
QString::QString(QChar ch)
{
d = DataPointer(Data::allocate(1), 1);
Q_CHECK_PTR(d.data());
d.data()[0] = ch.unicode();
d.data()[1] = '\0';
}
@ -2507,6 +2511,7 @@ void QString::reallocData(qsizetype alloc, QArrayData::AllocationOption option)
if (d->needsDetach() || cannotUseReallocate) {
DataPointer dd(Data::allocate(alloc, option), qMin(alloc, d.size));
Q_CHECK_PTR(dd.data());
if (dd.size > 0)
::memcpy(dd.data(), d.data(), dd.size * sizeof(QChar));
dd.data()[dd.size] = 0;
@ -2523,6 +2528,7 @@ void QString::reallocGrowData(qsizetype n)
if (d->needsDetach()) {
DataPointer dd(DataPointer::allocateGrow(d, n, QArrayData::GrowsAtEnd));
Q_CHECK_PTR(dd.data());
dd->copyAppend(d.data(), d.data() + d.size);
dd.data()[dd.size] = 0;
d = dd;
@ -2726,6 +2732,7 @@ QString& QString::insert(qsizetype i, const QChar *unicode, qsizetype size)
DataPointer detached{}; // construction is free
if (d->needsDetach() || i + size - d->size > d.freeSpaceAtEnd()) {
detached = DataPointer::allocateGrow(d, i + size - d->size, Data::GrowsAtEnd);
Q_CHECK_PTR(detached.data());
detached->copyAppend(d.constBegin(), d.constEnd());
d.swap(detached);
}
@ -5118,6 +5125,7 @@ QString QString::fromLatin1(QByteArrayView ba)
d = DataPointer::fromRawData(&_empty, 0);
} else {
d = DataPointer(Data::allocate(ba.size()), ba.size());
Q_CHECK_PTR(d.data());
d.data()[ba.size()] = '\0';
char16_t *dst = d.data();

View File

@ -235,6 +235,9 @@ QArrayData::reallocateUnaligned(QArrayData *data, void *dataPointer,
const qsizetype headerSize = sizeof(QArrayData);
qsizetype allocSize = calculateBlockSize(capacity, objectSize, headerSize, option);
if (Q_UNLIKELY(allocSize < 0))
return qMakePair<QArrayData *, void *>(nullptr, nullptr);
const qptrdiff offset = dataPointer
? reinterpret_cast<char *>(dataPointer) - reinterpret_cast<char *>(data)
: headerSize;

View File

@ -286,6 +286,7 @@ public:
void reallocate(qsizetype alloc, QArrayData::AllocationOption option)
{
auto pair = Data::reallocateUnaligned(this->d, this->ptr, alloc, option);
Q_CHECK_PTR(pair.second);
Q_ASSERT(pair.first != nullptr);
this->d = pair.first;
this->ptr = pair.second;
@ -849,6 +850,7 @@ public:
void reallocate(qsizetype alloc, QArrayData::AllocationOption option)
{
auto pair = Data::reallocateUnaligned(this->d, this->ptr, alloc, option);
Q_CHECK_PTR(pair.second);
Q_ASSERT(pair.first != nullptr);
this->d = pair.first;
this->ptr = pair.second;