Prevent negative size in QBitArray, QVector and QVarLengthArray ctors.

As shown in QTBUG-24345, QBitArray will exhibit invalid reads when
initialised with a negative size and run under valgrind.

QVector and QVarLengthArray both cause a crash if initialised with a
negative size.

This patch enforces sizes greater than or equal to 0 with asserts and
existing if statements, and hence impose no performance penalty for
release builds.

Task-number: QTBUG-24345
Task-number: QTBUG-30037

Change-Id: I9a969f6016e0a59904a60bbfe9e5360e6f523b87
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Mitch Curtis 2013-05-30 14:51:18 +02:00 committed by The Qt Project
parent f36374727e
commit 9aa24645eb
3 changed files with 8 additions and 3 deletions

View File

@ -122,7 +122,8 @@ QT_BEGIN_NAMESPACE
*/
QBitArray::QBitArray(int size, bool value)
{
if (!size) {
Q_ASSERT_X(size >= 0, "QBitArray::QBitArray", "Size must be greater than or equal to 0.");
if (size <= 0) {
d.resize(0);
return;
}

View File

@ -197,6 +197,8 @@ private:
template <class T, int Prealloc>
Q_INLINE_TEMPLATE QVarLengthArray<T, Prealloc>::QVarLengthArray(int asize)
: s(asize) {
Q_STATIC_ASSERT_X(Prealloc > 0, "QVarLengthArray Prealloc must be greater than 0.");
Q_ASSERT_X(s >= 0, "QVarLengthArray::QVarLengthArray()", "Size must be greater than or equal to 0.");
if (s > Prealloc) {
ptr = reinterpret_cast<T *>(malloc(s * sizeof(T)));
Q_CHECK_PTR(ptr);

View File

@ -398,7 +398,8 @@ QVector<T> &QVector<T>::operator=(const QVector<T> &v)
template <typename T>
QVector<T>::QVector(int asize)
{
if (Q_LIKELY(asize)) {
Q_ASSERT_X(asize >= 0, "QVector::QVector", "Size must be greater than or equal to 0.");
if (Q_LIKELY(asize > 0)) {
d = Data::allocate(asize);
d->size = asize;
defaultConstruct(d->begin(), d->end());
@ -410,7 +411,8 @@ QVector<T>::QVector(int asize)
template <typename T>
QVector<T>::QVector(int asize, const T &t)
{
if (asize) {
Q_ASSERT_X(asize >= 0, "QVector::QVector", "Size must be greater than or equal to 0.");
if (asize > 0) {
d = Data::allocate(asize);
d->size = asize;
T* i = d->end();