summaryrefslogtreecommitdiffstats
path: root/src/corelib/tools/qarraydata.cpp
diff options
context:
space:
mode:
authorThiago Macieira <thiago.macieira@intel.com>2015-06-05 00:41:36 +0200
committerThiago Macieira <thiago.macieira@intel.com>2016-06-09 15:32:14 +0000
commit0a78d918f0f411e0da2242a84a396f169154f5d6 (patch)
tree891bd0591f94bd390e12d71ef524ee19fb0d0f72 /src/corelib/tools/qarraydata.cpp
parent43ff604f9453edb24154c2ab5ea72bafe0fc501d (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.cpp34
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) {