diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2015-06-05 00:41:36 +0200 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2016-06-09 15:32:14 +0000 |
commit | 0a78d918f0f411e0da2242a84a396f169154f5d6 (patch) | |
tree | 891bd0591f94bd390e12d71ef524ee19fb0d0f72 /src/corelib/tools/qarraydata.cpp | |
parent | 43ff604f9453edb24154c2ab5ea72bafe0fc501d (diff) |
Replace qAllocMore with a pair of more useful functions
The first is "exact", not "more": qCalculateBlockSize. It ensures that
there's no overflow in multiplying, adding the header size or when
converting back to an int.
The second is the replacement for qAllocMore: it calculates the block
size like the first, but increases the block size to accommodate future
appends. The number of elements that fit in the block is also returned.
Task-number: QTBUG-41230
Change-Id: I52dd43c12685407bb9a6ffff13f5da09f816e667
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/corelib/tools/qarraydata.cpp')
-rw-r--r-- | src/corelib/tools/qarraydata.cpp | 34 |
1 files changed, 13 insertions, 21 deletions
diff --git a/src/corelib/tools/qarraydata.cpp b/src/corelib/tools/qarraydata.cpp index 36f1997a6c..55af7256be 100644 --- a/src/corelib/tools/qarraydata.cpp +++ b/src/corelib/tools/qarraydata.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. +** Copyright (C) 2016 Intel Corporation. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtCore module of the Qt Toolkit. @@ -87,29 +88,20 @@ QArrayData *QArrayData::allocate(size_t objectSize, size_t alignment, if (!(options & RawData)) headerSize += (alignment - Q_ALIGNOF(QArrayData)); - // Allocate additional space if array is growing - if (options & Grow) { - - // Guard against integer overflow when multiplying. - if (capacity > std::numeric_limits<size_t>::max() / objectSize) - return 0; - - size_t alloc; - if (mul_overflow(objectSize, capacity, &alloc)) - return 0; - - // Make sure qAllocMore won't overflow qAllocMore. - if (headerSize > size_t(MaxAllocSize) || alloc > size_t(MaxAllocSize) - headerSize) - return 0; - - capacity = qAllocMore(int(alloc), int(headerSize)) / int(objectSize); - } + if (headerSize > size_t(MaxAllocSize)) + return 0; + // Calculate the byte size + // allocSize = objectSize * capacity + headerSize, but checked for overflow + // plus padded to grow in size size_t allocSize; - if (mul_overflow(objectSize, capacity, &allocSize)) - return 0; - if (add_overflow(allocSize, headerSize, &allocSize)) - return 0; + if (options & Grow) { + auto r = qCalculateGrowingBlockSize(capacity, objectSize, headerSize); + capacity = r.elementCount; + allocSize = r.size; + } else { + allocSize = qCalculateBlockSize(capacity, objectSize, headerSize); + } QArrayData *header = static_cast<QArrayData *>(::malloc(allocSize)); if (header) { |