Clean up SkPathRef::makeSpace.

Note that this does not clean up the users of this function, which
may themselves be subject to other overflow issues.

BUG=chromium:728936

Change-Id: I3eaa7627c3b6ff49296ea2618a0157dacdc1d9cc
Reviewed-on: https://skia-review.googlesource.com/29121
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Mike Klein <mtklein@chromium.org>
Reviewed-by: Ben Wagner <bungeman@google.com>
This commit is contained in:
Ben Wagner 2017-07-31 16:57:01 -04:00 committed by Skia Commit-Bot
parent 402e463877
commit ac32662d12

View File

@ -16,7 +16,7 @@
#include "SkRRect.h"
#include "SkRect.h"
#include "SkRefCnt.h"
#include <stddef.h> // ptrdiff_t
#include "SkTemplates.h"
class SkRBuffer;
class SkWBuffer;
@ -433,31 +433,35 @@ private:
*/
void makeSpace(size_t size) {
SkDEBUGCODE(this->validate();)
ptrdiff_t growSize = size - fFreeSpace;
if (growSize <= 0) {
if (size <= fFreeSpace) {
return;
}
size_t growSize = size - fFreeSpace;
size_t oldSize = this->currSize();
// round to next multiple of 8 bytes
growSize = (growSize + 7) & ~static_cast<size_t>(7);
// we always at least double the allocation
if (static_cast<size_t>(growSize) < oldSize) {
if (growSize < oldSize) {
growSize = oldSize;
}
if (growSize < kMinSize) {
growSize = kMinSize;
}
size_t newSize = oldSize + growSize;
constexpr size_t maxSize = std::numeric_limits<size_t>::max();
size_t newSize;
if (growSize <= maxSize - oldSize) {
newSize = oldSize + growSize;
} else {
SK_ABORT("Path too big.");
}
// Note that realloc could memcpy more than we need. It seems to be a win anyway. TODO:
// encapsulate this.
fPoints = reinterpret_cast<SkPoint*>(sk_realloc_throw(fPoints, newSize));
size_t oldVerbSize = fVerbCnt * sizeof(uint8_t);
void* newVerbsDst = reinterpret_cast<void*>(
reinterpret_cast<intptr_t>(fPoints) + newSize - oldVerbSize);
void* oldVerbsSrc = reinterpret_cast<void*>(
reinterpret_cast<intptr_t>(fPoints) + oldSize - oldVerbSize);
void* newVerbsDst = SkTAddOffset<void>(fPoints, newSize - oldVerbSize);
void* oldVerbsSrc = SkTAddOffset<void>(fPoints, oldSize - oldVerbSize);
memmove(newVerbsDst, oldVerbsSrc, oldVerbSize);
fVerbs = reinterpret_cast<uint8_t*>(reinterpret_cast<intptr_t>(fPoints) + newSize);
fVerbs = SkTAddOffset<uint8_t>(fPoints, newSize);
fFreeSpace += growSize;
SkDEBUGCODE(this->validate();)
}