From 6abfc992b9d70837d42fcef3f2e2637464063899 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Abecasis?= Date: Wed, 4 Apr 2012 15:00:41 +0200 Subject: Make reallocData() take (unsigned) size, including null The parameter represents an allocation size and unsigned matches the Q*Data::alloc member it ultimately represents (even if they currently differ in accounting for the null). There's still work up for grabs to ensure we avoid integer overflows when growing. Change-Id: Ib092fec37ec2ceed37bebfdc52e2de27b336328f Reviewed-by: Thiago Macieira --- src/corelib/tools/qbytearray.cpp | 30 +++++++++++++++--------------- src/corelib/tools/qbytearray.h | 8 ++++---- src/corelib/tools/qstring.cpp | 28 ++++++++++++++-------------- src/corelib/tools/qstring.h | 10 +++++----- 4 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/corelib/tools/qbytearray.cpp b/src/corelib/tools/qbytearray.cpp index 32834ebd7e..43f666e075 100644 --- a/src/corelib/tools/qbytearray.cpp +++ b/src/corelib/tools/qbytearray.cpp @@ -919,7 +919,7 @@ QByteArray &QByteArray::operator=(const char *str) } else { int len = strlen(str); if (d->ref.isShared() || len > int(d->alloc) || (len < d->size && len < int(d->alloc) >> 1)) - reallocData(len); + reallocData(uint(len) + 1u); x = d; memcpy(x->data(), str, len + 1); // include null terminator x->size = len; @@ -1432,7 +1432,7 @@ void QByteArray::resize(int size) } else { if (d->ref.isShared() || size > int(d->alloc) || (!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1)) - reallocData(size, true); + reallocData(uint(size) + 1u, true); if (d->alloc) { d->size = size; d->data()[size] = '\0'; @@ -1459,17 +1459,17 @@ QByteArray &QByteArray::fill(char ch, int size) return *this; } -void QByteArray::reallocData(int alloc, bool grow) +void QByteArray::reallocData(uint alloc, bool grow) { if (grow) - alloc = qAllocMore(alloc + 1, sizeof(Data)) - 1; + alloc = qAllocMore(alloc, sizeof(Data)); if (d->ref.isShared() || IS_RAW_DATA(d)) { - Data *x = static_cast(malloc(sizeof(Data) + alloc + 1)); + Data *x = static_cast(malloc(sizeof(Data) + alloc)); Q_CHECK_PTR(x); x->ref.initializeOwned(); - x->size = qMin(alloc, d->size); - x->alloc = alloc; + x->size = qMin(int(alloc) - 1, d->size); + x->alloc = alloc - 1u; x->capacityReserved = d->capacityReserved; x->offset = sizeof(QByteArrayData); ::memcpy(x->data(), d->data(), x->size); @@ -1478,9 +1478,9 @@ void QByteArray::reallocData(int alloc, bool grow) free(d); d = x; } else { - Data *x = static_cast(::realloc(d, sizeof(Data) + alloc + 1)); + Data *x = static_cast(::realloc(d, sizeof(Data) + alloc)); Q_CHECK_PTR(x); - x->alloc = alloc; + x->alloc = alloc - 1u; x->offset = sizeof(QByteArrayData); d = x; } @@ -1566,7 +1566,7 @@ QByteArray &QByteArray::prepend(const char *str, int len) { if (str) { if (d->ref.isShared() || d->size + len > int(d->alloc)) - reallocData(d->size + len, true); + reallocData(uint(d->size + len) + 1u, true); memmove(d->data()+len, d->data(), d->size); memcpy(d->data(), str, len); d->size += len; @@ -1584,7 +1584,7 @@ QByteArray &QByteArray::prepend(const char *str, int len) QByteArray &QByteArray::prepend(char ch) { if (d->ref.isShared() || d->size + 1 > int(d->alloc)) - reallocData(d->size + 1, true); + reallocData(uint(d->size) + 2u, true); memmove(d->data()+1, d->data(), d->size); d->data()[0] = ch; ++d->size; @@ -1622,7 +1622,7 @@ QByteArray &QByteArray::append(const QByteArray &ba) *this = ba; } else if (ba.d != &shared_null.ba) { if (d->ref.isShared() || d->size + ba.d->size > int(d->alloc)) - reallocData(d->size + ba.d->size, true); + reallocData(uint(d->size + ba.d->size) + 1u, true); memcpy(d->data() + d->size, ba.d->data(), ba.d->size); d->size += ba.d->size; d->data()[d->size] = '\0'; @@ -1656,7 +1656,7 @@ QByteArray& QByteArray::append(const char *str) if (str) { int len = strlen(str); if (d->ref.isShared() || d->size + len > int(d->alloc)) - reallocData(d->size + len, true); + reallocData(uint(d->size + len) + 1u, true); memcpy(d->data() + d->size, str, len + 1); // include null terminator d->size += len; } @@ -1681,7 +1681,7 @@ QByteArray &QByteArray::append(const char *str, int len) len = qstrlen(str); if (str && len) { if (d->ref.isShared() || d->size + len > int(d->alloc)) - reallocData(d->size + len, true); + reallocData(uint(d->size + len) + 1u, true); memcpy(d->data() + d->size, str, len); // include null terminator d->size += len; d->data()[d->size] = '\0'; @@ -1698,7 +1698,7 @@ QByteArray &QByteArray::append(const char *str, int len) QByteArray& QByteArray::append(char ch) { if (d->ref.isShared() || d->size + 1 > int(d->alloc)) - reallocData(d->size + 1, true); + reallocData(uint(d->size) + 2u, true); d->data()[d->size++] = ch; d->data()[d->size] = '\0'; return *this; diff --git a/src/corelib/tools/qbytearray.h b/src/corelib/tools/qbytearray.h index 37c5f72040..287245182a 100644 --- a/src/corelib/tools/qbytearray.h +++ b/src/corelib/tools/qbytearray.h @@ -406,7 +406,7 @@ private: static const QStaticByteArrayData<1> shared_null; static const QStaticByteArrayData<1> shared_empty; Data *d; - void reallocData(int alloc, bool grow = false); + void reallocData(uint alloc, bool grow = false); void expand(int i); QByteArray nulTerminated() const; @@ -445,7 +445,7 @@ inline const char *QByteArray::data() const inline const char *QByteArray::constData() const { return d->data(); } inline void QByteArray::detach() -{ if (d->ref.isShared() || (d->offset != sizeof(QByteArrayData))) reallocData(d->size); } +{ if (d->ref.isShared() || (d->offset != sizeof(QByteArrayData))) reallocData(uint(d->size) + 1u); } inline bool QByteArray::isDetached() const { return !d->ref.isShared(); } inline QByteArray::QByteArray(const QByteArray &a) : d(a.d) @@ -457,7 +457,7 @@ inline int QByteArray::capacity() const inline void QByteArray::reserve(int asize) { if (d->ref.isShared() || asize > int(d->alloc)) - reallocData(asize); + reallocData(uint(asize) + 1u); if (!d->capacityReserved) { // cannot set unconditionally, since d could be the shared_null/shared_empty (which is const) @@ -468,7 +468,7 @@ inline void QByteArray::reserve(int asize) inline void QByteArray::squeeze() { if (d->ref.isShared() || d->size < int(d->alloc)) - reallocData(d->size); + reallocData(uint(d->size) + 1u); if (d->capacityReserved) { // cannot set unconditionally, since d could be shared_null or diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 2bb439d703..bc39eafb6d 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -1236,7 +1236,7 @@ void QString::resize(int size) } else { if (d->ref.isShared() || size > int(d->alloc) || (!d->capacityReserved && size < d->size && size < int(d->alloc) >> 1)) - reallocData(size, true); + reallocData(uint(size) + 1u, true); if (d->alloc) { d->size = size; d->data()[size] = '\0'; @@ -1294,17 +1294,17 @@ void QString::resize(int size) \sa reserve(), capacity() */ -void QString::reallocData(int alloc, bool grow) +void QString::reallocData(uint alloc, bool grow) { if (grow) - alloc = qAllocMore((alloc+1) * sizeof(QChar), sizeof(Data)) / sizeof(QChar) - 1; + alloc = qAllocMore(alloc * sizeof(QChar), sizeof(Data)) / sizeof(QChar); if (d->ref.isShared() || IS_RAW_DATA(d)) { - Data *x = static_cast(::malloc(sizeof(Data) + (alloc+1) * sizeof(QChar))); + Data *x = static_cast(::malloc(sizeof(Data) + alloc * sizeof(QChar))); Q_CHECK_PTR(x); x->ref.initializeOwned(); - x->size = qMin(alloc, d->size); - x->alloc = (uint) alloc; + x->size = qMin(int(alloc) - 1, d->size); + x->alloc = alloc - 1u; x->capacityReserved = d->capacityReserved; x->offset = sizeof(QStringData); ::memcpy(x->data(), d->data(), x->size * sizeof(QChar)); @@ -1313,10 +1313,10 @@ void QString::reallocData(int alloc, bool grow) QString::free(d); d = x; } else { - Data *p = static_cast(::realloc(d, sizeof(Data) + (alloc+1) * sizeof(QChar))); + Data *p = static_cast(::realloc(d, sizeof(Data) + alloc * sizeof(QChar))); Q_CHECK_PTR(p); d = p; - d->alloc = alloc; + d->alloc = alloc - 1u; d->offset = sizeof(QStringData); } } @@ -1525,7 +1525,7 @@ QString &QString::append(const QString &str) operator=(str); } else { if (d->ref.isShared() || d->size + str.d->size > int(d->alloc)) - reallocData(d->size + str.d->size, true); + reallocData(uint(d->size + str.d->size) + 1u, true); memcpy(d->data() + d->size, str.d->data(), str.d->size * sizeof(QChar)); d->size += str.d->size; d->data()[d->size] = '\0'; @@ -1545,7 +1545,7 @@ QString &QString::append(const QLatin1String &str) if (s) { int len = str.size(); if (d->ref.isShared() || d->size + len > int(d->alloc)) - reallocData(d->size + len, true); + reallocData(uint(d->size + len) + 1u, true); ushort *i = d->data() + d->size; while ((*i++ = *s++)) ; @@ -1588,7 +1588,7 @@ QString &QString::append(const QLatin1String &str) QString &QString::append(QChar ch) { if (d->ref.isShared() || d->size + 1 > int(d->alloc)) - reallocData(d->size + 1, true); + reallocData(uint(d->size) + 2u, true); d->data()[d->size++] = ch.unicode(); d->data()[d->size] = '\0'; return *this; @@ -2809,7 +2809,7 @@ QString& QString::replace(const QRegExp &rx, const QString &after) if (isEmpty() && rx2.indexIn(*this) == -1) return *this; - reallocData(d->size); + reallocData(uint(d->size) + 1u); int index = 0; int numCaptures = rx2.captureCount(); @@ -2972,7 +2972,7 @@ QString &QString::replace(const QRegularExpression &re, const QString &after) if (!iterator.hasNext()) // no matches at all return *this; - reallocData(d->size); + reallocData(uint(d->size) + 1u); int numCaptures = re.captureCount(); @@ -5076,7 +5076,7 @@ const ushort *QString::utf16() const { if (IS_RAW_DATA(d)) { // ensure '\0'-termination for ::fromRawData strings - const_cast(this)->reallocData(d->size); + const_cast(this)->reallocData(uint(d->size) + 1u); } return d->data(); } diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index d09e3b5ab2..a902f5f375 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -370,7 +370,7 @@ public: inline QString &operator+=(QChar c) { if (d->ref.isShared() || d->size + 1 > int(d->alloc)) - reallocData(d->size + 1, true); + reallocData(uint(d->size) + 2u, true); d->data()[d->size++] = c.unicode(); d->data()[d->size] = '\0'; return *this; @@ -646,7 +646,7 @@ private: Data *d; static void free(Data *); - void reallocData(int alloc, bool grow = false); + void reallocData(uint alloc, bool grow = false); void expand(int i); void updateProperties() const; QString multiArg(int numArgs, const QString **args) const; @@ -742,7 +742,7 @@ inline QChar *QString::data() inline const QChar *QString::constData() const { return reinterpret_cast(d->data()); } inline void QString::detach() -{ if (d->ref.isShared() || (d->offset != sizeof(QStringData))) reallocData(d->size); } +{ if (d->ref.isShared() || (d->offset != sizeof(QStringData))) reallocData(uint(d->size) + 1u); } inline bool QString::isDetached() const { return !d->ref.isShared(); } inline QString &QString::operator=(const QLatin1String &s) @@ -908,7 +908,7 @@ inline QString::~QString() { if (!d->ref.deref()) free(d); } inline void QString::reserve(int asize) { if (d->ref.isShared() || asize > int(d->alloc)) - reallocData(asize); + reallocData(uint(asize) + 1u); if (!d->capacityReserved) { // cannot set unconditionally, since d could be the shared_null/shared_empty (which is const) @@ -919,7 +919,7 @@ inline void QString::reserve(int asize) inline void QString::squeeze() { if (d->ref.isShared() || d->size < int(d->alloc)) - reallocData(d->size); + reallocData(uint(d->size) + 1u); if (d->capacityReserved) { // cannot set unconditionally, since d could be shared_null or -- cgit v1.2.3