aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkArenaAlloc.cpp
diff options
context:
space:
mode:
authorGravatar Ben Wagner <bungeman@google.com>2017-07-24 16:11:31 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-07-24 21:55:55 +0000
commit6229b1240aae8961a4bf34493b964d944a0a06ee (patch)
tree9db3a9f562dfa9fec5851060d5967412069701b3 /src/core/SkArenaAlloc.cpp
parent7881409baaadd3352d77529a86cdf4d535c1744e (diff)
Control crash ArenaAlloc for unsatisfiable requests.
BUG=chromium:747043 Change-Id: I24b757d75098a1125dcdf908a3aeffe98b16e66d Reviewed-on: https://skia-review.googlesource.com/26372 Commit-Queue: Ben Wagner <bungeman@google.com> Reviewed-by: Mike Klein <mtklein@chromium.org>
Diffstat (limited to 'src/core/SkArenaAlloc.cpp')
-rw-r--r--src/core/SkArenaAlloc.cpp23
1 files changed, 18 insertions, 5 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;
}