diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/SkArenaAlloc.cpp | 23 | ||||
-rw-r--r-- | src/core/SkArenaAlloc.h | 5 |
2 files changed, 22 insertions, 6 deletions
diff --git a/src/core/SkArenaAlloc.cpp b/src/core/SkArenaAlloc.cpp index 5d02d85368..450f0dac6e 100644 --- a/src/core/SkArenaAlloc.cpp +++ b/src/core/SkArenaAlloc.cpp @@ -8,6 +8,7 @@ #include <algorithm> #include <cstddef> #include "SkArenaAlloc.h" +#include "SkTypes.h" static char* end_chain(char*) { return nullptr; } @@ -109,19 +110,31 @@ void SkArenaAlloc::ensureSpace(uint32_t size, uint32_t alignment) { // This must be conservative to add the right amount of extra memory to handle the alignment // padding. constexpr uint32_t alignof_max_align_t = 8; - uint32_t objSizeAndOverhead = size + headerSize + sizeof(Footer); + constexpr uint32_t maxSize = std::numeric_limits<uint32_t>::max(); + constexpr uint32_t overhead = headerSize + sizeof(Footer); + SkASSERT_RELEASE(size <= maxSize - overhead); + uint32_t objSizeAndOverhead = size + overhead; if (alignment > alignof_max_align_t) { - objSizeAndOverhead += alignment - 1; + uint32_t alignmentOverhead = alignment - 1; + SkASSERT_RELEASE(objSizeAndOverhead <= maxSize - alignmentOverhead); + objSizeAndOverhead += alignmentOverhead; } - uint32_t allocationSize = std::max(objSizeAndOverhead, fExtraSize * fFib0); - fFib0 += fFib1; - std::swap(fFib0, fFib1); + uint32_t minAllocationSize; + if (fExtraSize <= maxSize / fFib0) { + minAllocationSize = fExtraSize * fFib0; + fFib0 += fFib1; + std::swap(fFib0, fFib1); + } else { + minAllocationSize = maxSize; + } + uint32_t allocationSize = std::max(objSizeAndOverhead, minAllocationSize); // Round up to a nice size. If > 32K align to 4K boundary else up to max_align_t. The > 32K // heuristic is from the JEMalloc behavior. { uint32_t mask = allocationSize > (1 << 15) ? (1 << 12) - 1 : 16 - 1; + SkASSERT_RELEASE(allocationSize <= maxSize - mask); allocationSize = (allocationSize + mask) & ~mask; } diff --git a/src/core/SkArenaAlloc.h b/src/core/SkArenaAlloc.h index f102cf6159..414e8c15e6 100644 --- a/src/core/SkArenaAlloc.h +++ b/src/core/SkArenaAlloc.h @@ -169,6 +169,7 @@ private: template <typename T> char* commonArrayAlloc(uint32_t count) { char* objStart; + SkASSERT_RELEASE(count <= std::numeric_limits<uint32_t>::max() / sizeof(T)); uint32_t arraySize = SkTo<uint32_t>(count * sizeof(T)); uint32_t alignment = SkTo<uint32_t>(alignof(T)); @@ -176,7 +177,9 @@ private: objStart = this->allocObject(arraySize, alignment); fCursor = objStart + arraySize; } else { - uint32_t totalSize = arraySize + sizeof(Footer) + sizeof(uint32_t); + constexpr uint32_t overhead = sizeof(Footer) + sizeof(uint32_t); + SkASSERT_RELEASE(arraySize <= std::numeric_limits<uint32_t>::max() - overhead); + uint32_t totalSize = arraySize + overhead; objStart = this->allocObjectWithFooter(totalSize, alignment); // Can never be UB because max value is alignof(T). |